@minimalstuff/ui 0.0.30 → 1.0.0-4

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,70 @@
1
+ # @minimalstuff/ui
2
+
3
+ React UI component library.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ pnpm add @minimalstuff/ui react react-dom
9
+ ```
10
+
11
+ Peer dependencies: React 18 or 19.
12
+
13
+ ## Usage
14
+
15
+ ```tsx
16
+ import { Button } from '@minimalstuff/ui';
17
+ import '@minimalstuff/ui/style.css';
18
+
19
+ export function App() {
20
+ return <Button variant="primary">Click me</Button>;
21
+ }
22
+ ```
23
+
24
+ ## Development
25
+
26
+ ```bash
27
+ pnpm install
28
+ pnpm run dev # Storybook on :6006
29
+ pnpm run lint
30
+ pnpm run test
31
+ pnpm run build # Library build → dist/
32
+ ```
33
+
34
+ ## Releasing
35
+
36
+ CI (lint, test, build) and npm publish run together when a GitHub Release is published.
37
+
38
+ ### Prerequisites
39
+
40
+ 1. **NPM token**
41
+ Create an automation token at [npmjs.com/access-tokens](https://www.npmjs.com/access-tokens) (scope: package publish for `@minimalstuff/ui`).
42
+
43
+ 2. **Repository secret**
44
+ In the repo: **Settings → Secrets and variables → Actions**. Add a secret named `NPM_TOKEN` with the token value.
45
+
46
+ ### Procedure
47
+
48
+ 1. **Bump version** (optional if using tag-based versioning):
49
+
50
+ ```bash
51
+ pnpm version 1.2.0 # or 1.2.0-alpha.0 for prerelease
52
+ git push && git push --tags
53
+ ```
54
+
55
+ 2. **Create a GitHub Release**
56
+ **Releases → Draft a new release**:
57
+ - Choose or create a tag (e.g. `v1.2.0`). Use the same version as in `package.json` if you bumped it; otherwise the workflow sets the package version from the tag (e.g. `v1.2.0` → `1.2.0`).
58
+ - Add release notes and publish.
59
+
60
+ 3. **Workflow**
61
+ The **CI & Publish** workflow runs on **release published**. It sets the package version from the tag, runs lint, test, build, then `pnpm publish --no-git-checks`. The package is published under the tag `latest` (or the tag you set for prereleases).
62
+
63
+ ### Prereleases
64
+
65
+ Semver prereleases (e.g. `1.0.0-0`, `1.0.0-alpha.1`) are supported. To avoid making them the default install:
66
+
67
+ - Publish with a dist-tag, e.g. `pnpm publish --tag next`, or
68
+ - Rely on consumers installing an explicit version: `pnpm add @minimalstuff/ui@1.0.0-alpha.1`.
69
+
70
+ If you want CI to publish prereleases automatically (e.g. on tag `v1.0.0-alpha.1`), add a separate workflow or extend the existing one to run on prerelease tags and use `--tag next`.
package/dist/index.d.ts CHANGED
@@ -1,358 +1,125 @@
1
- /// <reference types="react" />
2
-
3
- import { AnchorHTMLAttributes } from 'react';
4
1
  import { ButtonHTMLAttributes } from 'react';
5
- import { ClassAttributes } from 'react';
6
- import { Context } from 'react';
7
- import { CSSProperties } from 'react';
8
- import { DetailedHTMLProps } from 'react';
9
- import { ElementType } from 'react';
10
- import { FormatOptionLabelMeta } from 'react-select';
11
- import { FormHTMLAttributes } from 'react';
12
- import { HTMLAttributes } from 'react';
13
- import { IconType } from 'react-icons/lib';
14
- import { ImgHTMLAttributes } from 'react';
2
+ import { FragmentProps } from 'react';
3
+ import { FunctionComponentElement } from 'react';
15
4
  import { InputHTMLAttributes } from 'react';
16
- import { JSX as JSX_2 } from 'react';
17
- import { JSX as JSX_3 } from '@emotion/react/jsx-runtime';
18
- import { LiHTMLAttributes } from 'react';
19
- import { MutableRefObject } from 'react';
20
- import { PropsWithChildren } from 'react';
5
+ import { JSX } from 'react/jsx-runtime';
6
+ import { JSXElementConstructor } from 'react';
7
+ import { ReactElement } from 'react';
21
8
  import { ReactNode } from 'react';
22
- import { RefObject } from 'react';
23
- import { RefType } from 'react-hotkeys-hook/dist/types';
24
- import { StyledComponent } from '@emotion/styled';
25
- import { Theme } from '@emotion/react';
26
-
27
- declare type Borders = {
28
- radius: {
29
- [key in SizeType]: string;
30
- };
31
- };
32
-
33
- export declare const Button: StyledComponent< {
34
- theme?: Theme | undefined;
35
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
36
- } & ButtonProps, DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {}>;
37
-
38
- declare type ButtonProps = {
39
- danger?: boolean;
40
- secondary?: boolean;
41
- };
42
-
43
- export declare function Checkbox({ name, label, checked, errors, onChange, required, reverse, inline, ...props }: InputProps): JSX.Element;
44
-
45
- export declare type Colors = {
46
- font: string;
47
- background: string;
48
- secondary: string;
49
- black: string;
50
- white: string;
51
- grey: FadedColor;
52
- blue: FadedColor;
53
- green: FadedColor;
54
- red: FadedColor;
55
- yellow: FadedColor;
56
- boxShadow: string;
57
- };
9
+ import { ReactPortal } from 'react';
10
+ import { TextareaHTMLAttributes } from 'react';
58
11
 
59
- export declare function Dropdown({ children, label, className, svgSize, }: DropdownProps): JSX_3.Element;
12
+ export declare function applyTheme(newTheme: Theme_2): void;
60
13
 
61
- export declare const DropdownContainer: StyledComponent< {
62
- theme?: Theme | undefined;
63
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
64
- } & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & {
65
- theme?: Theme | undefined;
66
- } & {
67
- show: boolean;
68
- }, {}, {}>;
14
+ export declare const BASE_INPUT_STYLES = "w-full rounded-md border border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-all duration-200 disabled:opacity-50 disabled:cursor-not-allowed";
69
15
 
70
- export declare const DropdownItemButton: StyledComponent< {
71
- theme?: Theme | undefined;
72
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
73
- } & {
74
- danger?: boolean | undefined;
75
- } & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & {
76
- theme?: Theme | undefined;
77
- }, {}, {}>;
16
+ export declare const Button: ({ variant, size, children, className, fullWidth, disabled, ...props }: ButtonProps) => JSX.Element;
78
17
 
79
- export declare const DropdownItemLink: StyledComponent< {
80
- theme?: Theme | undefined;
81
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
82
- } & {
83
- danger?: boolean | undefined;
84
- } & ClassAttributes<HTMLAnchorElement> & AnchorHTMLAttributes<HTMLAnchorElement> & {
85
- theme?: Theme | undefined;
86
- }, {}, {}>;
87
-
88
- export declare const DropdownLabel: StyledComponent< {
89
- theme?: Theme | undefined;
90
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
91
- }, DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
92
-
93
- declare interface DropdownProps {
18
+ declare interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
19
+ variant?: ButtonVariant;
20
+ size?: ButtonSize;
94
21
  children: ReactNode;
95
- label: ReactNode | string;
96
22
  className?: string;
97
- svgSize?: number;
23
+ fullWidth?: boolean;
98
24
  }
99
25
 
100
- export declare function ExternalLink({ children, title, ...props }: AnchorHTMLAttributes<HTMLAnchorElement> & PropsWithChildren & {
101
- style?: CSSProperties;
102
- title?: string;
103
- className?: string;
104
- }): JSX_3.Element;
26
+ declare type ButtonSize = 'xs' | 'sm' | 'md' | 'lg';
105
27
 
106
- export declare type FadedColor = {
107
- lightest: string;
108
- light: string;
109
- default: string;
110
- dark: string;
111
- darkest: string;
112
- };
28
+ declare type ButtonVariant = 'primary' | 'secondary' | 'ghost' | 'outline' | 'subtle' | 'danger';
113
29
 
114
- declare type FadedColor_2 = {
115
- lightest: string;
116
- light: string;
117
- default: string;
118
- dark: string;
119
- darkest: string;
120
- };
30
+ export declare function CharacterCount({ current, min, max, showMin, showMax, }: CharacterCountProps): JSX.Element;
121
31
 
122
- declare interface FadedColorGenerator {
123
- color: string;
124
- fadeStep?: number;
32
+ declare interface CharacterCountProps {
33
+ current: number;
34
+ min?: number;
35
+ max?: number;
36
+ showMin?: boolean;
37
+ showMax?: boolean;
125
38
  }
126
39
 
127
- declare type FontSizes = {
128
- [key in SizeType]: string;
129
- };
130
-
131
- export declare const Form: StyledComponent< {
132
- theme?: Theme | undefined;
133
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
134
- }, DetailedHTMLProps<FormHTMLAttributes<HTMLFormElement>, HTMLFormElement>, {}>;
135
-
136
- declare type FormFieldProps = {
137
- required?: boolean;
138
- inline?: boolean;
139
- reverse?: boolean;
140
- };
141
-
142
- export declare function generateFadedColors(props: FadedColorGenerator): FadedColor_2;
40
+ export declare function ClientOnly({ children, fallback }: ClientOnlyProps): string | number | bigint | boolean | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | Promise<string | number | bigint | boolean | ReactPortal | ReactElement<unknown, string | JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | FunctionComponentElement<FragmentProps> | null;
143
41
 
144
- declare type GlobalHotkeysContext = {
145
- globalHotkeysEnabled: boolean;
146
- setGlobalHotkeysEnabled: (value: boolean) => void;
147
- };
42
+ declare interface ClientOnlyProps extends React.PropsWithChildren {
43
+ fallback?: React.ReactNode;
44
+ }
148
45
 
149
- declare const GlobalHotkeysContext = createContext<GlobalHotkeysContext>(
150
- iGlobalHotkeysContextState
151
- );
46
+ export declare const IconButton: ({ icon, "aria-label": ariaLabel, variant, size, className, children, ref, ...props }: IconButtonProps) => JSX.Element;
152
47
 
153
- declare interface InputProps extends Omit<InputHTMLAttributes<HTMLInputElement> & FormFieldProps, 'onChange'> {
154
- label: string;
155
- name: string;
156
- checked: boolean;
157
- errors?: string[];
158
- onChange?: (name: string, checked: boolean) => void;
48
+ declare interface IconButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
49
+ icon: string;
50
+ 'aria-label': string;
51
+ variant?: 'default' | 'ghost' | 'danger' | 'outline';
52
+ size?: 'sm' | 'md' | 'lg';
53
+ children?: ReactNode;
54
+ ref?: React.Ref<HTMLButtonElement>;
159
55
  }
160
56
 
161
- declare interface InputProps_2 extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
162
- name: string;
57
+ export declare function Input({ label, error, showCharCount, minLength, maxLength, className, wrapperClassName, value, defaultValue, onChange, id, ...props }: InputProps): JSX.Element;
58
+
59
+ declare interface InputProps extends InputHTMLAttributes<HTMLInputElement> {
163
60
  label?: string;
164
- value?: string;
165
- errors?: string[];
166
- onChange?: (name: string, value: string) => void;
167
- formFieldClassname?: string;
61
+ error?: string;
62
+ showCharCount?: boolean;
63
+ minLength?: number;
64
+ maxLength?: number;
65
+ className?: string;
66
+ wrapperClassName?: string;
168
67
  }
169
68
 
170
- declare const KEYS = {
171
- ARROW_DOWN,
172
- ARROW_UP,
173
- ESCAPE_KEY,
174
- };
175
-
176
- declare type Medias = {
177
- [key in ScreenType]: string;
178
- };
179
-
180
- export declare function Modal({ title, children, opened, hideCloseBtn, className, close, }: ModalProps): false | JSX_3.Element;
181
-
182
- export declare const ModalBody: StyledComponent< {
183
- theme?: Theme | undefined;
184
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
185
- }, DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
186
-
187
- export declare const ModalCloseBtn: StyledComponent< {
188
- theme?: Theme | undefined;
189
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
190
- }, DetailedHTMLProps<ButtonHTMLAttributes<HTMLButtonElement>, HTMLButtonElement>, {}>;
191
-
192
- export declare const ModalContainer: StyledComponent< {
193
- theme?: Theme | undefined;
194
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
195
- } & ClassAttributes<HTMLDivElement> & HTMLAttributes<HTMLDivElement> & {
196
- theme?: Theme | undefined;
197
- }, {}, {}>;
198
-
199
- export declare const ModalHeader: StyledComponent< {
200
- theme?: Theme | undefined;
201
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
202
- }, DetailedHTMLProps<HTMLAttributes<HTMLHeadingElement>, HTMLHeadingElement>, {}>;
69
+ export declare function Modal({ isOpen, onClose, title, children, size, className, }: ModalProps): ReactPortal | null;
203
70
 
204
71
  declare interface ModalProps {
205
- title?: string;
72
+ isOpen?: boolean;
73
+ onClose?: () => void;
74
+ title?: ReactNode;
206
75
  children: ReactNode;
207
- opened: boolean;
208
- hideCloseBtn?: boolean;
76
+ size?: 'sm' | 'md' | 'lg' | 'xl';
209
77
  className?: string;
210
- close: () => void;
211
- }
212
-
213
- export declare const ModalWrapper: StyledComponent< {
214
- theme?: Theme | undefined;
215
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
216
- }, DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
217
-
218
- declare type Option_2<T> = {
219
- label: string | number;
220
- value: T;
221
- };
222
-
223
- export declare const rgba: (hex: string, alpha: number) => string;
224
-
225
- export declare const RoundedImage: StyledComponent< {
226
- theme?: Theme | undefined;
227
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
228
- } & RoundedImageProps, DetailedHTMLProps<ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>, {}>;
229
-
230
- declare interface RoundedImageProps {
231
- size?: number;
232
- }
233
-
234
- declare type ScreenType =
235
- | 'mobile'
236
- | 'tablet'
237
- | 'small_desktop'
238
- | 'medium_desktop'
239
- | 'large_desktop'
240
- | 'xlarge_desktop';
241
-
242
- export declare function Selector<T = string | number>({ name, label, value, options, onChangeCallback, formatOptionLabel, required, ...props }: SelectorProps<T>): JSX.Element;
243
-
244
- declare interface SelectorProps<T> extends Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'> {
245
- label: string;
246
- value: T;
247
- name: string;
248
- errors?: string[];
249
- options: Option_2<T>[];
250
- onChangeCallback?: (value: T) => void;
251
- formatOptionLabel?: (data: Option_2<T>, formatOptionLabelMeta: FormatOptionLabelMeta<Option_2<T>>) => ReactNode;
252
78
  }
253
79
 
254
- declare type ShortcutOptions = {
255
- enabled?: boolean;
256
- disableGlobalCheck?: boolean;
257
- };
258
-
259
- declare type SizeType = 'xs' | 's' | 'm' | 'l' | 'xl';
260
-
261
- declare type SpeedType = 'fast' | 'normal' | 'slow';
262
-
263
- export declare function StyleReset(): JSX_3.Element;
264
-
265
- export declare interface Tab {
80
+ export declare interface TabItem {
266
81
  title: string;
267
82
  content: ReactNode;
268
- icon?: IconType;
269
- danger?: boolean;
83
+ disabled?: boolean;
84
+ icon?: string;
270
85
  }
271
86
 
272
- export declare const TabItem: StyledComponent< {
273
- theme?: Theme | undefined;
274
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
275
- } & {
276
- active?: boolean | undefined;
277
- danger?: boolean | undefined;
278
- }, DetailedHTMLProps<LiHTMLAttributes<HTMLLIElement>, HTMLLIElement>, {}>;
87
+ export declare function Tabs({ items, defaultIndex, className, tabListClassName, panelClassName, onChange, }: TabsProps): JSX.Element;
279
88
 
280
- export declare const TabList: StyledComponent< {
281
- theme?: Theme | undefined;
282
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
283
- }, DetailedHTMLProps<HTMLAttributes<HTMLUListElement>, HTMLUListElement>, {}>;
284
-
285
- export declare const TabPanel: StyledComponent< {
286
- theme?: Theme | undefined;
287
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
288
- }, DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {}>;
289
-
290
- export declare function Tabs({ tabs }: TabsProps): JSX_3.Element;
291
-
292
- export declare interface TabsProps {
293
- tabs: Tab[];
89
+ declare interface TabsProps {
90
+ items: TabItem[];
91
+ defaultIndex?: number;
92
+ className?: string;
93
+ tabListClassName?: string;
94
+ panelClassName?: string;
95
+ onChange?: (index: number) => void;
294
96
  }
295
97
 
296
- export declare function Textbox({ name, label, value, errors, onChange, required, formFieldClassname, ...props }: InputProps_2): JSX.Element;
297
-
298
- export declare const TextEllipsis: StyledComponent< {
299
- theme?: Theme | undefined;
300
- as?: ElementType<any, keyof JSX_2.IntrinsicElements> | undefined;
301
- } & TextEllipsisProps, DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>, {}>;
302
-
303
- declare type TextEllipsisProps = {
304
- lines?: number;
305
- };
98
+ export declare function Textarea({ label, error, showCharCount, minLength, maxLength, className, wrapperClassName, value, defaultValue, onChange, id, ...props }: TextareaProps): JSX.Element;
306
99
 
307
- export declare const _ThemeContext: Context< {
308
- isDarkTheme: boolean;
309
- toggleDarkTheme: (_value: boolean) => void;
310
- }>;
311
-
312
- export declare function ThemeContextProvider({ children, onPreferenceChange, }: {
313
- onPreferenceChange?: (isDarkTheme: boolean) => void;
314
- } & PropsWithChildren): JSX_3.Element;
100
+ declare interface TextareaProps extends TextareaHTMLAttributes<HTMLTextAreaElement> {
101
+ label?: string;
102
+ error?: string;
103
+ showCharCount?: boolean;
104
+ minLength?: number;
105
+ maxLength?: number;
106
+ className?: string;
107
+ wrapperClassName?: string;
108
+ }
315
109
 
316
- declare type Transitions = {
317
- delay: {
318
- [key in SpeedType]: string;
319
- };
320
- };
110
+ export declare type Theme = 'light' | 'dark' | 'system';
321
111
 
322
- export declare interface UITheme {
323
- colors: Colors;
324
- borders: Borders;
325
- medias: Medias;
326
- transitions: Transitions;
327
- fontSizes: FontSizes;
328
- }
112
+ declare type Theme_2 = 'light' | 'dark' | 'system';
329
113
 
330
- /**
331
- * This Hook can be used for detecting clicks outside the Opened Menu
332
- */
333
- export declare function useClickOutside(ref: RefObject<HTMLElement>, onClickOutside: () => void): void;
114
+ export declare function ThemeToggle(): JSX.Element;
334
115
 
335
- export declare const useGlobalHotkeys: () => GlobalHotkeysContext;
116
+ /** React hook that returns true if the component has mounted client-side */
117
+ export declare const useClientOnly: () => boolean;
336
118
 
337
- export declare function useShortcut(key: keyof typeof KEYS, cb: () => void, { enabled, disableGlobalCheck }?: ShortcutOptions): MutableRefObject<RefType<HTMLElement>>;
119
+ export declare const useIsClient: () => boolean;
338
120
 
339
- export declare const useThemeSwitcher: () => {
340
- isDarkTheme: boolean;
341
- toggleDarkTheme: (_value: boolean) => void;
342
- };
121
+ export declare function useRunAfterAnimation(durationMs: number): (callback: () => void) => () => void;
343
122
 
344
- export declare const useToggle: (defaultValue?: boolean) => {
345
- isShowing: boolean;
346
- toggle: () => void;
347
- open: () => void;
348
- close: () => void;
349
- };
123
+ export declare const withClientOnly: <T extends object>(Component: React.ComponentType<T>) => React.ComponentType<T>;
350
124
 
351
125
  export { }
352
-
353
-
354
- declare module 'vitest' {
355
- interface Assertion<T = any> extends jest.Matchers<void, T>, TestingLibraryMatchers<T, void> {
356
- }
357
- }
358
-
@@ -0,0 +1,2 @@
1
+ @keyframes tabs-panel-in{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.tabs-panel-inner{animation:.25s ease-out tabs-panel-in}
2
+ /*$vite$:1*/