@cleen/ui-core 0.1.0 → 0.1.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 +40 -0
- package/dist/index.d.ts +258 -0
- package/dist/index.js +758 -0
- package/dist/styles.css +4560 -0
- package/package.json +42 -42
- package/tailwind-entry.css +81 -81
- package/tailwind.config.js +10 -10
- package/tailwind.preset.js +30 -30
- package/src/hooks/useAnimateNumber.ts +0 -56
- package/src/hooks/useControlled.ts +0 -40
- package/src/hooks/useDebounce.ts +0 -17
- package/src/hooks/useDisclosure.ts +0 -33
- package/src/hooks/useForm.ts +0 -38
- package/src/hooks/useOutsideClick.ts +0 -42
- package/src/hooks/usePaginationState.ts +0 -39
- package/src/hooks/usePositionClose.ts +0 -69
- package/src/hooks/useValidation.ts +0 -33
- package/src/hooks/useWatchResize.ts +0 -52
- package/src/index.ts +0 -21
- package/src/store/colors.ts +0 -98
- package/src/types/position.ts +0 -9
- package/src/types/styles.ts +0 -24
- package/src/types/utils.ts +0 -6
- package/src/utils/audio.ts +0 -69
- package/src/utils/cn.ts +0 -13
- package/src/utils/colors.ts +0 -159
- package/src/utils/images.ts +0 -42
- package/src/utils/object.ts +0 -86
- package/src/utils/position.ts +0 -140
- package/src/utils/string.ts +0 -27
- package/styles/react-day-styles.css +0 -457
- package/tsconfig.json +0 -27
- package/tsup.config.ts +0 -10
package/README.md
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# @cleen/ui-core
|
|
2
|
+
|
|
3
|
+
Shared foundation for the Cleen UI library — Tailwind CSS configuration, custom hooks, utilities, and theming primitives used by `@cleen/ui` and `@cleen/ui-pro`.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @cleen/ui-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Tailwind Setup
|
|
12
|
+
|
|
13
|
+
Extend your Tailwind config with the Cleen preset and import the CSS:
|
|
14
|
+
|
|
15
|
+
```js
|
|
16
|
+
// tailwind.config.js
|
|
17
|
+
import cleenPreset from '@cleen/ui-core/tailwind-preset';
|
|
18
|
+
|
|
19
|
+
export default {
|
|
20
|
+
presets: [cleenPreset],
|
|
21
|
+
};
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
```css
|
|
25
|
+
/* your entry CSS */
|
|
26
|
+
@import '@cleen/ui-core/tailwind-entry.css';
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Or import the pre-built stylesheet directly:
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import '@cleen/ui-core/styles.css';
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
> **Note:** All Tailwind classes use the `cleen-` prefix. Components must be wrapped in a `.cleen` element for styles to apply.
|
|
36
|
+
|
|
37
|
+
## Peer Dependencies
|
|
38
|
+
|
|
39
|
+
- `react` ^18.3.1
|
|
40
|
+
- `react-dom` ^18.3.1
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,258 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { RefObject, CSSProperties } from 'react';
|
|
3
|
+
import * as zustand_middleware from 'zustand/middleware';
|
|
4
|
+
import * as zustand from 'zustand';
|
|
5
|
+
import { ClassValue } from 'clsx';
|
|
6
|
+
|
|
7
|
+
interface UseAnimateNumberProps {
|
|
8
|
+
targetNumber: number;
|
|
9
|
+
defaultNumber?: number;
|
|
10
|
+
duration?: number;
|
|
11
|
+
disabled?: boolean;
|
|
12
|
+
easeOut?: boolean;
|
|
13
|
+
}
|
|
14
|
+
declare const useAnimateNumber: ({ targetNumber, defaultNumber, duration, disabled, easeOut, }: UseAnimateNumberProps) => number;
|
|
15
|
+
|
|
16
|
+
interface UseControlledProps<T> {
|
|
17
|
+
value?: T;
|
|
18
|
+
defaultValue?: T;
|
|
19
|
+
onChange?: (value: T) => void;
|
|
20
|
+
}
|
|
21
|
+
declare const useControlled: <T>({ value, defaultValue, onChange, }: UseControlledProps<T>) => {
|
|
22
|
+
value: T | undefined;
|
|
23
|
+
isControlled: boolean;
|
|
24
|
+
handleChange: (newValue: T) => void;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
declare const useDebounce: <T>(value: T, delay: number) => T;
|
|
28
|
+
|
|
29
|
+
interface UseDisclosureProps {
|
|
30
|
+
value?: boolean;
|
|
31
|
+
setValue?: (value: boolean) => void;
|
|
32
|
+
}
|
|
33
|
+
declare const useDisclosure: (props?: UseDisclosureProps) => {
|
|
34
|
+
isOpen: boolean;
|
|
35
|
+
open: () => void;
|
|
36
|
+
close: () => void;
|
|
37
|
+
toggle: () => void;
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
interface UseFormProps<T> {
|
|
41
|
+
defaultValue: T | null;
|
|
42
|
+
resetOnDefaultValueChange?: boolean;
|
|
43
|
+
}
|
|
44
|
+
declare const useForm: <T extends Record<string, unknown>>({ defaultValue, resetOnDefaultValueChange, }: UseFormProps<T>) => {
|
|
45
|
+
form: T | null;
|
|
46
|
+
isDirty: boolean;
|
|
47
|
+
setForm: react.Dispatch<react.SetStateAction<T | null>>;
|
|
48
|
+
setField: (field: keyof T, value: T[keyof T]) => void;
|
|
49
|
+
reset: () => void;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
interface UseOutsideClickProps {
|
|
53
|
+
refs: RefObject<HTMLElement | null>[];
|
|
54
|
+
handler: (event: MouseEvent | TouchEvent) => void;
|
|
55
|
+
enabled?: boolean;
|
|
56
|
+
}
|
|
57
|
+
declare function useOutsideClick({ refs, handler, enabled, }: UseOutsideClickProps): void;
|
|
58
|
+
|
|
59
|
+
interface PaginationOptions {
|
|
60
|
+
initialPage?: number;
|
|
61
|
+
initialPageSize?: number;
|
|
62
|
+
}
|
|
63
|
+
interface PaginationState {
|
|
64
|
+
page: number;
|
|
65
|
+
setPage: (page: number) => void;
|
|
66
|
+
pageSize: number;
|
|
67
|
+
setPageSize: (size: number) => void;
|
|
68
|
+
handleNextPage: (page: number) => void;
|
|
69
|
+
handlePreviousPage: (page: number) => void;
|
|
70
|
+
handlePageChange: (page: number) => void;
|
|
71
|
+
}
|
|
72
|
+
declare function usePaginationState(options?: PaginationOptions): PaginationState;
|
|
73
|
+
|
|
74
|
+
type Position = 'bottom-left' | 'bottom-right' | 'bottom' | 'top-left' | 'top-right' | 'top' | 'left' | 'right';
|
|
75
|
+
|
|
76
|
+
interface UsePositionCloseProps {
|
|
77
|
+
triggerRef: RefObject<HTMLElement | null>;
|
|
78
|
+
targetRef: RefObject<HTMLElement | null>;
|
|
79
|
+
position?: Position;
|
|
80
|
+
offset?: number;
|
|
81
|
+
isOpen: boolean;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Hook to calculate fixed positioning for overlays relative to trigger elements.
|
|
85
|
+
* Handles viewport-aware position optimization and click-outside detection.
|
|
86
|
+
*/
|
|
87
|
+
declare const usePositionClose: ({ triggerRef, targetRef, position, offset, isOpen, }: UsePositionCloseProps) => {
|
|
88
|
+
positionStyles: {
|
|
89
|
+
top: number;
|
|
90
|
+
left: number;
|
|
91
|
+
} | {
|
|
92
|
+
top: number;
|
|
93
|
+
left: number;
|
|
94
|
+
};
|
|
95
|
+
optimalPosition: Position | undefined;
|
|
96
|
+
isMounted: boolean;
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
declare const useValidation: <T>(defaultValue: Partial<T>) => {
|
|
100
|
+
errors: Partial<T>;
|
|
101
|
+
setError: (field: keyof T, value: Partial<T>[keyof T]) => void;
|
|
102
|
+
setErrors: react.Dispatch<react.SetStateAction<Partial<T>>>;
|
|
103
|
+
clearError: (field: keyof T) => void;
|
|
104
|
+
clearErrors: () => void;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
interface UseWidthDynamicResizeParams<T> {
|
|
108
|
+
ref: RefObject<T>;
|
|
109
|
+
skip?: boolean;
|
|
110
|
+
}
|
|
111
|
+
declare const useWidthDynamicResize: <T extends HTMLElement | null>({ ref, skip }: UseWidthDynamicResizeParams<T>, deps: unknown[]) => void;
|
|
112
|
+
|
|
113
|
+
declare const colorVars: readonly ["white", "black", "gray", "pink", "purple", "indigo", "blue", "primary", "success", "warning", "error", "brand", "sidebar", "background"];
|
|
114
|
+
type ColorVar = (typeof colorVars)[number];
|
|
115
|
+
interface UseCleenColorsStore {
|
|
116
|
+
colors: Partial<Record<ColorVar, string>>;
|
|
117
|
+
getColors: () => Partial<Record<ColorVar, string>>;
|
|
118
|
+
getColor: (color: ColorVar) => string;
|
|
119
|
+
setColor: (colorVar: ColorVar, value: string) => void;
|
|
120
|
+
setColors: (colors: Partial<Record<ColorVar, string>>) => void;
|
|
121
|
+
resetColors: () => void;
|
|
122
|
+
resetColor: (color: ColorVar) => void;
|
|
123
|
+
}
|
|
124
|
+
declare const useCleenColors: zustand.UseBoundStore<Omit<zustand.StoreApi<UseCleenColorsStore>, "setState" | "persist"> & {
|
|
125
|
+
setState(partial: UseCleenColorsStore | Partial<UseCleenColorsStore> | ((state: UseCleenColorsStore) => UseCleenColorsStore | Partial<UseCleenColorsStore>), replace?: false | undefined): unknown;
|
|
126
|
+
setState(state: UseCleenColorsStore | ((state: UseCleenColorsStore) => UseCleenColorsStore), replace: true): unknown;
|
|
127
|
+
persist: {
|
|
128
|
+
setOptions: (options: Partial<zustand_middleware.PersistOptions<UseCleenColorsStore, UseCleenColorsStore, unknown>>) => void;
|
|
129
|
+
clearStorage: () => void;
|
|
130
|
+
rehydrate: () => Promise<void> | void;
|
|
131
|
+
hasHydrated: () => boolean;
|
|
132
|
+
onHydrate: (fn: (state: UseCleenColorsStore) => void) => () => void;
|
|
133
|
+
onFinishHydration: (fn: (state: UseCleenColorsStore) => void) => () => void;
|
|
134
|
+
getOptions: () => Partial<zustand_middleware.PersistOptions<UseCleenColorsStore, UseCleenColorsStore, unknown>>;
|
|
135
|
+
};
|
|
136
|
+
}>;
|
|
137
|
+
|
|
138
|
+
interface UseCleenOverlays {
|
|
139
|
+
overlays: string[];
|
|
140
|
+
addOverlay: (id: string) => void;
|
|
141
|
+
removeOverlay: (id: string) => void;
|
|
142
|
+
clearOverlays: () => void;
|
|
143
|
+
}
|
|
144
|
+
declare const useCleenOverlays: zustand.UseBoundStore<Omit<zustand.StoreApi<UseCleenOverlays>, "setState" | "persist"> & {
|
|
145
|
+
setState(partial: UseCleenOverlays | Partial<UseCleenOverlays> | ((state: UseCleenOverlays) => UseCleenOverlays | Partial<UseCleenOverlays>), replace?: false | undefined): unknown;
|
|
146
|
+
setState(state: UseCleenOverlays | ((state: UseCleenOverlays) => UseCleenOverlays), replace: true): unknown;
|
|
147
|
+
persist: {
|
|
148
|
+
setOptions: (options: Partial<zustand_middleware.PersistOptions<UseCleenOverlays, UseCleenOverlays, unknown>>) => void;
|
|
149
|
+
clearStorage: () => void;
|
|
150
|
+
rehydrate: () => Promise<void> | void;
|
|
151
|
+
hasHydrated: () => boolean;
|
|
152
|
+
onHydrate: (fn: (state: UseCleenOverlays) => void) => () => void;
|
|
153
|
+
onFinishHydration: (fn: (state: UseCleenOverlays) => void) => () => void;
|
|
154
|
+
getOptions: () => Partial<zustand_middleware.PersistOptions<UseCleenOverlays, UseCleenOverlays, unknown>>;
|
|
155
|
+
};
|
|
156
|
+
}>;
|
|
157
|
+
|
|
158
|
+
interface ComponentClassnames<T extends {
|
|
159
|
+
classNames?: {
|
|
160
|
+
[key: string]: string | object;
|
|
161
|
+
};
|
|
162
|
+
}> {
|
|
163
|
+
className?: string;
|
|
164
|
+
classNames?: T['classNames'];
|
|
165
|
+
}
|
|
166
|
+
interface ComponentStyles<T extends {
|
|
167
|
+
styles?: {
|
|
168
|
+
[key: string]: CSSProperties | object;
|
|
169
|
+
};
|
|
170
|
+
}> {
|
|
171
|
+
style?: CSSProperties;
|
|
172
|
+
styles?: T['styles'];
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
type HintedString<KnownValues extends string> = (string & {}) | KnownValues;
|
|
176
|
+
type ArrayElement<ArrayType extends readonly unknown[]> = ArrayType extends readonly (infer ElementType)[] ? ElementType : never;
|
|
177
|
+
|
|
178
|
+
/** Minimal synchronous PCM WAV encoder – no extra deps needed =w= */
|
|
179
|
+
declare const encodeWav: (buffer: AudioBuffer) => Blob;
|
|
180
|
+
declare const trimBlob: (blob: Blob, startSec: number, endSec: number) => Promise<Blob>;
|
|
181
|
+
|
|
182
|
+
declare const cn: (...inputs: ClassValue[]) => string;
|
|
183
|
+
|
|
184
|
+
type RGBA = [number, number, number, number];
|
|
185
|
+
declare class ColorHelpers {
|
|
186
|
+
/**
|
|
187
|
+
* Calculates the Delta E (CIE94) between two RGB colors.
|
|
188
|
+
*
|
|
189
|
+
* Delta E is a metric for color difference. Based on the value, we can describe how different the colors are:
|
|
190
|
+
*
|
|
191
|
+
* Perception Levels:
|
|
192
|
+
* - Delta E <= 1.0: Not perceptible by human eyes.
|
|
193
|
+
* - Delta E between 1-2: Perceptible through close observation.
|
|
194
|
+
* - Delta E between 2-10: Perceptible at a glance.
|
|
195
|
+
* - Delta E between 11-49: Colors are more similar than opposite.
|
|
196
|
+
* - Delta E = 100: Colors are exact opposites.
|
|
197
|
+
*
|
|
198
|
+
* @param {Array<number>} rgb1 - The first RGB color as an array [R, G, B].
|
|
199
|
+
* @param {Array<number>} rgb2 - The second RGB color as an array [R, G, B].
|
|
200
|
+
* @returns {number} The Delta E value representing the difference between the two colors.
|
|
201
|
+
*
|
|
202
|
+
* @example
|
|
203
|
+
* deltaE([128, 0, 255], [128, 0, 255]); // 0
|
|
204
|
+
* deltaE([128, 0, 255], [128, 0, 230]); // 3.175
|
|
205
|
+
* deltaE([128, 0, 255], [255, 0, 0]); // 61.24
|
|
206
|
+
*/
|
|
207
|
+
static deltaE(rgbA: RGBA, rgbB: RGBA): number;
|
|
208
|
+
static rgb2lab(rgb: RGBA): number[];
|
|
209
|
+
static isSimilar(color1: string, color2: string, defaultDeltaE?: number): boolean;
|
|
210
|
+
static adjustColorForContrast(hexColor: string, amount?: number): string;
|
|
211
|
+
static getComputedColor(color?: string): string | undefined;
|
|
212
|
+
static getComputedRgb(color?: string): string | undefined;
|
|
213
|
+
static trasparentize(color?: string, value?: number): string;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
interface PicsumOptions {
|
|
217
|
+
width: number;
|
|
218
|
+
height?: number;
|
|
219
|
+
grayscale?: boolean;
|
|
220
|
+
blur?: number;
|
|
221
|
+
seed?: string;
|
|
222
|
+
}
|
|
223
|
+
declare const getRandomImageUrl: (options: PicsumOptions) => string;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Deep partial type — makes all properties optional recursively.
|
|
227
|
+
*/
|
|
228
|
+
type PartialDeep<T> = T extends (...args: unknown[]) => unknown ? T : T extends Array<infer U> ? Array<PartialDeep<U>> : T extends object ? {
|
|
229
|
+
[K in keyof T]?: PartialDeep<T[K]>;
|
|
230
|
+
} : T | undefined;
|
|
231
|
+
/**
|
|
232
|
+
* Recursively apply values on top of default values.
|
|
233
|
+
*
|
|
234
|
+
* Rules / assumptions:
|
|
235
|
+
* - Plain objects are merged recursively.
|
|
236
|
+
* - Arrays are replaced entirely by provided values (not concatenated).
|
|
237
|
+
* - If a provided value is `undefined`, the default is kept.
|
|
238
|
+
* - If a provided value is `null`, it overrides the default.
|
|
239
|
+
* - Non-plain objects (Date, RegExp, Map, Set, class instances) are replaced by the provided value when present.
|
|
240
|
+
*
|
|
241
|
+
* Example:
|
|
242
|
+
* const defaults = { a: 1, b: { c: 2, d: [1] } };
|
|
243
|
+
* const vals = { b: { c: 3 } };
|
|
244
|
+
* applyDefaults(defaults, vals) // => { a: 1, b: { c: 3, d: [1] } }
|
|
245
|
+
*/
|
|
246
|
+
declare function applyDefaults<T>(defaults: T, values?: PartialDeep<T>): T;
|
|
247
|
+
|
|
248
|
+
declare const calculateOptimalPosition: (overlayRect: DOMRect, triggerRect: DOMRect, preferredPosition: Position) => Position;
|
|
249
|
+
declare const calculatePositionValues: (overlayRect: DOMRect, triggerRect: DOMRect, position: Position, offset?: number) => {
|
|
250
|
+
top: number;
|
|
251
|
+
left: number;
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
declare const formatFileSize: (bytes?: number) => string;
|
|
255
|
+
declare const formatAudioTime: (seconds: number) => string;
|
|
256
|
+
declare const getCreatedDate: (date: string) => string;
|
|
257
|
+
|
|
258
|
+
export { type ArrayElement, ColorHelpers, type ColorVar, type ComponentClassnames, type ComponentStyles, type HintedString, type PartialDeep, type Position, applyDefaults, calculateOptimalPosition, calculatePositionValues, cn, encodeWav, formatAudioTime, formatFileSize, getCreatedDate, getRandomImageUrl, trimBlob, useAnimateNumber, useCleenColors, useCleenOverlays, useControlled, useDebounce, useDisclosure, useForm, useOutsideClick, usePaginationState, usePositionClose, useValidation, useWidthDynamicResize };
|