cekat-ui 1.3.0 → 1.3.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
@@ -4,96 +4,143 @@ A modern, lightweight **React UI component library** built with **TypeScript**,
4
4
 
5
5
  `cekat-ui` is designed to be:
6
6
 
7
- - Composable (shadcn / Radix-inspired)
8
- - Tree-shakeable
9
- - Fully typed
10
- - ✅ Framework-agnostic (works with Next.js, Vite, CRA, etc.)
7
+ - Composable (compound components, Radix / react-aria-inspired)
8
+ - Tree-shakeable (ESM + UMD, fully typed)
9
+ - Framework-friendly (Next.js, Vite, and other React 18 apps)
10
+
11
+ This repo uses **Yarn Classic** (`yarn.lock` v1).
11
12
 
12
13
  ---
13
14
 
14
- ## Features
15
+ ## Features
16
+
17
+ Public exports from `cekat-ui`:
15
18
 
16
- - Button (compound component)
17
- - Checkbox
18
- - Radio Group
19
- - Toggle (Switch)
20
- - Tooltip
21
- - Tailwind CSS styling
19
+ | Area | Components |
20
+ | ------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
21
+ | Actions & feedback | `Button`, `Toggle`, `Checkbox`, `RadioGroup` / `RadioGroupItem`, `Tooltip`, `Alert`, `Loading`, `Dropdown` |
22
+ | Display | `Avatar`, `AvatarGroup`, `AvatarLabelGroup`, `AvatarProfilePhoto`, `Badge`, `BadgeGroup`, `Tag` |
23
+ | Navigation | `Tab` / `TabList`, `TabBrowser` / `TabBrowserBar` |
24
+ | Inputs | `Input` (compound `Input.Prefix` / `Input.Suffix`), `PhoneInput`, `CardNumberInput`, `SaleAmountInput`, `InputCounter`, `Textarea`, `MultiSelectInput`, `InputDropdown`, `WebsiteInput`, `WebsiteCopyInput` |
25
+
26
+ Icons used in stories and examples come from [`@tabler/icons-react`](https://tabler.io/icons).
22
27
 
23
28
  ---
24
29
 
25
- ## 📦 Installation
30
+ ## Installation
26
31
 
27
32
  ```bash
28
33
  npm install cekat-ui
34
+ # or
35
+ yarn add cekat-ui
36
+ ```
29
37
 
30
- or
38
+ Peer dependencies:
31
39
 
32
- yarn add cekat-ui
40
+ ```json
41
+ {
42
+ "react": "^18.3.1",
43
+ "react-dom": "^18.3.1"
44
+ }
33
45
  ```
34
46
 
47
+ ---
48
+
35
49
  ## Styles
36
50
 
37
- `cekat-ui` ships with prebuilt styles. Import once in your app entry file.
51
+ `cekat-ui` ships prebuilt CSS. Import it once in the app entry file. The file includes component styles and base typography (Nunito); it does not fetch remote fonts.
38
52
 
39
- Next.js (App Router):
53
+ Next.js App Router (`app/layout.tsx`):
40
54
 
41
- ````ts
55
+ ```tsx
42
56
  import 'cekat-ui/style.css';
57
+ ```
43
58
 
59
+ Next.js Pages Router (`pages/_app.tsx`):
44
60
 
61
+ ```tsx
62
+ import 'cekat-ui/style.css';
63
+ ```
64
+
65
+ ### Tailwind preset
66
+
67
+ To use design tokens (`primary`, `bg-primary-50`, loading keyframes, and so on) in your own Tailwind classes, add the published preset:
68
+
69
+ ```js
70
+ // tailwind.config.js / tailwind.config.cjs
71
+ module.exports = {
72
+ presets: [require('cekat-ui/tailwind-preset')],
73
+ content: ['./app/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'],
74
+ };
75
+ ```
76
+
77
+ `style.css` is enough for component appearance. The preset is for token classes in the consuming app. A working Next 14 example lives in `fixtures/next-consumer`.
78
+
79
+ ---
45
80
 
46
81
  ## Usage
47
82
 
48
83
  ### Button
84
+
85
+ `Button` is built on [React Aria Components `Button`](https://react-aria.adobe.com/Button). Use `onPress` for mouse, touch, and keyboard. `isPending` keeps the control focusable, blocks further presses, and announces progress. `onClick` and `disabled` still work as aliases for `onPress` and `isDisabled`.
86
+
49
87
  ```tsx
50
88
  import { Button } from 'cekat-ui';
51
89
 
52
90
  export default function Example() {
53
91
  return (
54
- <Button size="md" tone="primary" variant="solid">
55
- Click me
92
+ <Button size="md" tone="primary" variant="solid" onPress={() => save()}>
93
+ Save
56
94
  </Button>
57
95
  );
58
96
  }
59
- ````
97
+ ```
60
98
 
61
99
  ### Compound usage
62
100
 
63
101
  ```tsx
102
+ import { IconChevronLeft } from '@tabler/icons-react';
103
+ import { Button } from 'cekat-ui';
104
+
64
105
  <Button>
65
106
  <Button.Icon>
66
- <IconChevronLeft size={16} />
107
+ <IconChevronLeft />
67
108
  </Button.Icon>
68
109
  <Button.Text>Submit</Button.Text>
69
- </Button>
110
+ </Button>;
70
111
  ```
71
112
 
72
- ## Components API
113
+ `Button.Icon` sizes the glyph from `size` (xs 18 · sm/md 20 · lg 24 · xl/2xl 28). Omit `size` on the icon.
73
114
 
74
- All components support:
115
+ `Button` sizes: `xs` | `sm` | `md` | `lg` | `xl` | `2xl`. Tone: `primary` | `destructive`. Variants include `solid`, `outline`, `ghost`, and `plain` / `plain-black` (link-style: hug content, 4px gap, no padding or radius).
75
116
 
76
- - `className` override
77
- - Controlled & uncontrolled usage
78
- - Keyboard & screen reader accessibility
79
- - Size variants (`sm`, `md`, `lg`)
117
+ ### Input
80
118
 
81
- For full props reference, see Storybook.
119
+ ```tsx
120
+ import { Input } from 'cekat-ui';
82
121
 
83
- ## Storybook
122
+ <Input placeholder="Search" />;
123
+ ```
84
124
 
85
- Run Storybook locally:
125
+ ---
86
126
 
87
- ```bash
88
- yarn dev
89
- ```
127
+ ## Components API
128
+
129
+ Most components accept `className` overrides. Sizes, variants, and controlled vs uncontrolled usage differ per component — they are not a single shared API.
130
+
131
+ For full props, variants, and interaction examples, use Storybook.
90
132
 
91
- Build static Storybook:
133
+ ---
134
+
135
+ ## Storybook
92
136
 
93
137
  ```bash
94
- yarn build:storybook
138
+ yarn dev # http://localhost:6006
139
+ yarn build:storybook # static build → storybook-static/
95
140
  ```
96
141
 
142
+ ---
143
+
97
144
  ## Testing
98
145
 
99
146
  Stories are component tests via [Storybook's Vitest addon](https://storybook.js.org/docs/writing-tests/integrations/vitest-addon). They run in Playwright Chromium (browser mode).
@@ -108,22 +155,34 @@ yarn test-storybook --run
108
155
 
109
156
  Install browser binaries once with `yarn playwright install chromium`. In Storybook, use the testing widget to run or watch the same tests.
110
157
 
111
- Smoke tests cover every story; interaction tests run any story `play` function.
158
+ Smoke tests cover every story; interaction tests run any story `play` function. Button contracts live in `stories/Button.behaviors.stories.tsx` (press, disabled, pending chrome, icon sizes, slots, ref).
112
159
 
113
- ## Peer Dependencies
160
+ ---
114
161
 
115
- ```json
116
- {
117
- "react": ">=18",
118
- "react-dom": ">=18"
119
- }
162
+ ## Local development
163
+
164
+ Node **22** (matches CI). After `yarn install`:
165
+
166
+ ```bash
167
+ yarn typecheck
168
+ yarn lint
169
+ yarn fmt:check
170
+ yarn test-storybook --run
171
+ yarn build:lib # ESM/UMD + dist/style.css
172
+ yarn check:pack # dist artifacts, publint, attw
173
+ yarn check:consumer # Next 14 smoke against the packed tarball
120
174
  ```
121
175
 
122
- ## Tech Stack
176
+ `yarn fmt` / `yarn lint:fix` apply formatting and lint fixes. Pre-commit runs `lint-staged` (oxfmt).
177
+
178
+ ---
179
+
180
+ ## Tech stack
123
181
 
124
- - React
125
- - TypeScript
126
- - Tailwind CSS
127
- - class-variance-authority
128
- - Storybook
129
- - Vite
182
+ - React 18 + TypeScript
183
+ - Tailwind CSS 3 + class-variance-authority / clsx / tailwind-merge
184
+ - react-aria-components (Button, tabs)
185
+ - @tabler/icons-react
186
+ - Storybook 10 + Vite 7
187
+ - Vitest (browser) + Playwright Chromium
188
+ - oxlint / oxfmt
package/dist/index.d.mts CHANGED
@@ -1,7 +1,10 @@
1
+ import { ButtonProps as ButtonProps_2 } from 'react-aria-components';
2
+ import { ButtonRenderProps } from 'react-aria-components';
1
3
  import { ClassValue } from 'clsx';
2
4
  import { default as default_2 } from 'react';
3
5
  import { JSX as JSX_2 } from 'react/jsx-runtime';
4
6
  import { Key } from 'react-aria-components';
7
+ import { PressEvent } from 'react-aria-components';
5
8
  import * as React_2 from 'react';
6
9
  import { ReactNode } from 'react';
7
10
 
@@ -12,7 +15,7 @@ export declare const Alert: {
12
15
 
13
16
  export declare interface AlertAction {
14
17
  label: React_2.ReactNode;
15
- onClick?: React_2.MouseEventHandler<HTMLButtonElement>;
18
+ onClick?: () => void;
16
19
  }
17
20
 
18
21
  export declare type AlertActionVariant = 'link' | 'button';
@@ -210,27 +213,34 @@ export declare type BadgeVariant = 'solid' | 'outline';
210
213
  export declare const Button: ButtonCompound;
211
214
 
212
215
  /** `ForwardRefExoticComponent` rather than `FC`: the base forwards a ref to its `<button>`. */
213
- declare type ButtonCompound = React_2.ForwardRefExoticComponent<ButtonProps & React_2.RefAttributes<HTMLButtonElement>> & {
216
+ export declare type ButtonCompound = React_2.ForwardRefExoticComponent<ButtonProps & React_2.RefAttributes<HTMLButtonElement>> & {
214
217
  Icon: React_2.FC<ButtonSubComponentProps>;
215
218
  Text: React_2.FC<ButtonSubComponentProps>;
216
219
  };
217
220
 
218
- declare interface ButtonProps extends React_2.ButtonHTMLAttributes<HTMLButtonElement> {
221
+ /** Figma Buttons/Button icon box: xs 18 · sm/md 20 · lg 24 · xl/2xl 28. */
222
+ export declare const buttonIconSizePx: Record<ButtonSize, number>;
223
+
224
+ export declare interface ButtonProps extends ButtonProps_2 {
219
225
  tone?: ButtonTone;
220
226
  size?: ButtonSize;
221
227
  variant?: ButtonVariant;
222
228
  iconOnly?: boolean;
229
+ /** Alias for `isDisabled`. Prefer `isDisabled`. */
230
+ disabled?: boolean;
223
231
  }
224
232
 
225
- declare type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
233
+ export { ButtonRenderProps }
226
234
 
227
- declare interface ButtonSubComponentProps {
235
+ export declare type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
236
+
237
+ export declare interface ButtonSubComponentProps {
228
238
  children: React_2.ReactNode;
229
239
  }
230
240
 
231
- declare type ButtonTone = 'primary' | 'destructive';
241
+ export declare type ButtonTone = 'primary' | 'destructive';
232
242
 
233
- declare type ButtonVariant = 'solid' | 'outline' | 'outline-primary' | 'ghost' | 'ghost-primary' | 'plain' | 'plain-black';
243
+ export declare type ButtonVariant = 'solid' | 'outline' | 'outline-primary' | 'ghost' | 'ghost-primary' | 'plain' | 'plain-black';
234
244
 
235
245
  export declare function CardNumberInput({ size, label, required, hint, error, disabled, placeholder, value, onChange, rightIcon, prefix, className, wrapperClassName, }: CardNumberInputProps): JSX_2.Element;
236
246
 
@@ -499,6 +509,8 @@ declare interface PhoneInputProps {
499
509
  wrapperClassName?: InputProps['wrapperClassName'];
500
510
  }
501
511
 
512
+ export { PressEvent }
513
+
502
514
  export declare const RadioGroup: ({ value, defaultValue, onValueChange, children, className, }: RadioGroupProps) => JSX_2.Element;
503
515
 
504
516
  export declare const RadioGroupItem: React_2.ForwardRefExoticComponent<RadioGroupItemProps & React_2.RefAttributes<HTMLButtonElement>>;
package/dist/index.d.ts CHANGED
@@ -1,7 +1,10 @@
1
+ import { ButtonProps as ButtonProps_2 } from 'react-aria-components';
2
+ import { ButtonRenderProps } from 'react-aria-components';
1
3
  import { ClassValue } from 'clsx';
2
4
  import { default as default_2 } from 'react';
3
5
  import { JSX as JSX_2 } from 'react/jsx-runtime';
4
6
  import { Key } from 'react-aria-components';
7
+ import { PressEvent } from 'react-aria-components';
5
8
  import * as React_2 from 'react';
6
9
  import { ReactNode } from 'react';
7
10
 
@@ -12,7 +15,7 @@ export declare const Alert: {
12
15
 
13
16
  export declare interface AlertAction {
14
17
  label: React_2.ReactNode;
15
- onClick?: React_2.MouseEventHandler<HTMLButtonElement>;
18
+ onClick?: () => void;
16
19
  }
17
20
 
18
21
  export declare type AlertActionVariant = 'link' | 'button';
@@ -210,27 +213,34 @@ export declare type BadgeVariant = 'solid' | 'outline';
210
213
  export declare const Button: ButtonCompound;
211
214
 
212
215
  /** `ForwardRefExoticComponent` rather than `FC`: the base forwards a ref to its `<button>`. */
213
- declare type ButtonCompound = React_2.ForwardRefExoticComponent<ButtonProps & React_2.RefAttributes<HTMLButtonElement>> & {
216
+ export declare type ButtonCompound = React_2.ForwardRefExoticComponent<ButtonProps & React_2.RefAttributes<HTMLButtonElement>> & {
214
217
  Icon: React_2.FC<ButtonSubComponentProps>;
215
218
  Text: React_2.FC<ButtonSubComponentProps>;
216
219
  };
217
220
 
218
- declare interface ButtonProps extends React_2.ButtonHTMLAttributes<HTMLButtonElement> {
221
+ /** Figma Buttons/Button icon box: xs 18 · sm/md 20 · lg 24 · xl/2xl 28. */
222
+ export declare const buttonIconSizePx: Record<ButtonSize, number>;
223
+
224
+ export declare interface ButtonProps extends ButtonProps_2 {
219
225
  tone?: ButtonTone;
220
226
  size?: ButtonSize;
221
227
  variant?: ButtonVariant;
222
228
  iconOnly?: boolean;
229
+ /** Alias for `isDisabled`. Prefer `isDisabled`. */
230
+ disabled?: boolean;
223
231
  }
224
232
 
225
- declare type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
233
+ export { ButtonRenderProps }
226
234
 
227
- declare interface ButtonSubComponentProps {
235
+ export declare type ButtonSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl' | '2xl';
236
+
237
+ export declare interface ButtonSubComponentProps {
228
238
  children: React_2.ReactNode;
229
239
  }
230
240
 
231
- declare type ButtonTone = 'primary' | 'destructive';
241
+ export declare type ButtonTone = 'primary' | 'destructive';
232
242
 
233
- declare type ButtonVariant = 'solid' | 'outline' | 'outline-primary' | 'ghost' | 'ghost-primary' | 'plain' | 'plain-black';
243
+ export declare type ButtonVariant = 'solid' | 'outline' | 'outline-primary' | 'ghost' | 'ghost-primary' | 'plain' | 'plain-black';
234
244
 
235
245
  export declare function CardNumberInput({ size, label, required, hint, error, disabled, placeholder, value, onChange, rightIcon, prefix, className, wrapperClassName, }: CardNumberInputProps): JSX_2.Element;
236
246
 
@@ -499,6 +509,8 @@ declare interface PhoneInputProps {
499
509
  wrapperClassName?: InputProps['wrapperClassName'];
500
510
  }
501
511
 
512
+ export { PressEvent }
513
+
502
514
  export declare const RadioGroup: ({ value, defaultValue, onValueChange, children, className, }: RadioGroupProps) => JSX_2.Element;
503
515
 
504
516
  export declare const RadioGroupItem: React_2.ForwardRefExoticComponent<RadioGroupItemProps & React_2.RefAttributes<HTMLButtonElement>>;