@pyck/react 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.
- package/dist/checkmark-CW-yHMvN.js +18 -0
- package/dist/chunk-BYypO7fO.js +18 -0
- package/dist/close-button-BM7ikbYh.js +52 -0
- package/dist/components/absolute-center/index.d.ts +11 -0
- package/dist/components/absolute-center/index.js +9 -0
- package/dist/components/action-bar/index.d.ts +21 -0
- package/dist/components/action-bar/index.js +35 -0
- package/dist/components/avatar/index.d.ts +22 -0
- package/dist/components/avatar/index.js +53 -0
- package/dist/components/badge/index.d.ts +11 -0
- package/dist/components/badge/index.js +9 -0
- package/dist/components/breadcrumb/index.d.ts +19 -0
- package/dist/components/breadcrumb/index.js +31 -0
- package/dist/components/button/index.d.ts +47 -0
- package/dist/components/button/index.js +3 -0
- package/dist/components/card/index.d.ts +19 -0
- package/dist/components/card/index.js +24 -0
- package/dist/components/carousel/index.d.ts +25 -0
- package/dist/components/carousel/index.js +65 -0
- package/dist/components/checkbox/index.d.ts +35 -0
- package/dist/components/checkbox/index.js +67 -0
- package/dist/components/checkmark/index.d.ts +26 -0
- package/dist/components/checkmark/index.js +3 -0
- package/dist/components/clipboard/index.d.ts +21 -0
- package/dist/components/clipboard/index.js +36 -0
- package/dist/components/collapsible/index.d.ts +18 -0
- package/dist/components/collapsible/index.js +23 -0
- package/dist/components/combobox/index.d.ts +32 -0
- package/dist/components/combobox/index.js +62 -0
- package/dist/components/data-list/index.d.ts +26 -0
- package/dist/components/data-list/index.js +39 -0
- package/dist/components/date-picker/index.d.ts +38 -0
- package/dist/components/date-picker/index.js +81 -0
- package/dist/components/dialog/index.d.ts +107 -0
- package/dist/components/dialog/index.js +295 -0
- package/dist/components/display-date-value/index.d.ts +3 -0
- package/dist/components/display-date-value/index.js +4 -0
- package/dist/components/display-value/index.d.ts +2 -0
- package/dist/components/display-value/index.js +3 -0
- package/dist/components/drawer/index.d.ts +28 -0
- package/dist/components/drawer/index.js +50 -0
- package/dist/components/drilldown-menu/index.d.ts +16 -0
- package/dist/components/drilldown-menu/index.js +123 -0
- package/dist/components/field/index.d.ts +21 -0
- package/dist/components/field/index.js +49 -0
- package/dist/components/fieldset/index.d.ts +23 -0
- package/dist/components/fieldset/index.js +32 -0
- package/dist/components/floating-panel/index.d.ts +23 -0
- package/dist/components/floating-panel/index.js +86 -0
- package/dist/components/for/index.d.ts +20 -0
- package/dist/components/for/index.js +9 -0
- package/dist/components/form/index.d.ts +41 -0
- package/dist/components/form/index.js +46 -0
- package/dist/components/format/index.d.ts +2 -0
- package/dist/components/format/index.js +3 -0
- package/dist/components/group/index.d.ts +11 -0
- package/dist/components/group/index.js +9 -0
- package/dist/components/heading/index.d.ts +12 -0
- package/dist/components/heading/index.js +8 -0
- package/dist/components/highlight/index.d.ts +17 -0
- package/dist/components/highlight/index.js +27 -0
- package/dist/components/icon/index.d.ts +19 -0
- package/dist/components/icon/index.js +3 -0
- package/dist/components/image/index.d.ts +22 -0
- package/dist/components/image/index.js +12 -0
- package/dist/components/input/index.d.ts +23 -0
- package/dist/components/input/index.js +21 -0
- package/dist/components/input-addon/index.d.ts +11 -0
- package/dist/components/input-addon/index.js +9 -0
- package/dist/components/input-group/index.d.ts +16 -0
- package/dist/components/input-group/index.js +29 -0
- package/dist/components/json-form-builder/index.d.ts +135 -0
- package/dist/components/json-form-builder/index.js +347 -0
- package/dist/components/kbd/index.d.ts +11 -0
- package/dist/components/kbd/index.js +9 -0
- package/dist/components/link/index.d.ts +11 -0
- package/dist/components/link/index.js +9 -0
- package/dist/components/listbox/index.d.ts +2 -0
- package/dist/components/listbox/index.js +3 -0
- package/dist/components/loader/index.d.ts +28 -0
- package/dist/components/loader/index.js +28 -0
- package/dist/components/locale/index.d.ts +2 -0
- package/dist/components/locale/index.js +3 -0
- package/dist/components/logo/index.d.ts +8 -0
- package/dist/components/logo/index.js +25 -0
- package/dist/components/mark/index.d.ts +11 -0
- package/dist/components/mark/index.js +9 -0
- package/dist/components/menu/index.d.ts +34 -0
- package/dist/components/menu/index.js +69 -0
- package/dist/components/number-input/index.d.ts +34 -0
- package/dist/components/number-input/index.js +51 -0
- package/dist/components/page-header/index.d.ts +18 -0
- package/dist/components/page-header/index.js +22 -0
- package/dist/components/pagination/index.d.ts +29 -0
- package/dist/components/pagination/index.js +45 -0
- package/dist/components/picker/index.d.ts +19 -0
- package/dist/components/picker/index.js +57 -0
- package/dist/components/popover/index.d.ts +30 -0
- package/dist/components/popover/index.js +50 -0
- package/dist/components/portal/index.d.ts +2 -0
- package/dist/components/portal/index.js +3 -0
- package/dist/components/progress/index.d.ts +19 -0
- package/dist/components/progress/index.js +47 -0
- package/dist/components/progress-circle/index.d.ts +19 -0
- package/dist/components/progress-circle/index.js +54 -0
- package/dist/components/radio-card-group/index.d.ts +21 -0
- package/dist/components/radio-card-group/index.js +29 -0
- package/dist/components/radio-group/index.d.ts +22 -0
- package/dist/components/radio-group/index.js +41 -0
- package/dist/components/scroll-area/index.d.ts +23 -0
- package/dist/components/scroll-area/index.js +41 -0
- package/dist/components/segment-group/index.d.ts +32 -0
- package/dist/components/segment-group/index.js +46 -0
- package/dist/components/select/index.d.ts +54 -0
- package/dist/components/select/index.js +93 -0
- package/dist/components/show/index.d.ts +11 -0
- package/dist/components/show/index.js +3 -0
- package/dist/components/skeleton/index.d.ts +23 -0
- package/dist/components/skeleton/index.js +17 -0
- package/dist/components/slider/index.d.ts +31 -0
- package/dist/components/slider/index.js +93 -0
- package/dist/components/span/index.d.ts +8 -0
- package/dist/components/span/index.js +3 -0
- package/dist/components/spinner/index.d.ts +11 -0
- package/dist/components/spinner/index.js +9 -0
- package/dist/components/spotlight/index.d.ts +28 -0
- package/dist/components/spotlight/index.js +165 -0
- package/dist/components/stat/index.d.ts +16 -0
- package/dist/components/stat/index.js +18 -0
- package/dist/components/steps/index.d.ts +36 -0
- package/dist/components/steps/index.js +61 -0
- package/dist/components/switch/index.d.ts +41 -0
- package/dist/components/switch/index.js +80 -0
- package/dist/components/table/index.d.ts +85 -0
- package/dist/components/table/index.js +144 -0
- package/dist/components/tabs/index.d.ts +18 -0
- package/dist/components/tabs/index.js +22 -0
- package/dist/components/tags-input/index.d.ts +29 -0
- package/dist/components/tags-input/index.js +48 -0
- package/dist/components/text/index.d.ts +12 -0
- package/dist/components/text/index.js +8 -0
- package/dist/components/textarea/index.d.ts +24 -0
- package/dist/components/textarea/index.js +22 -0
- package/dist/components/toast/index.d.ts +25 -0
- package/dist/components/toast/index.js +76 -0
- package/dist/components/toggle-group/index.d.ts +16 -0
- package/dist/components/toggle-group/index.js +19 -0
- package/dist/components/tooltip/index.d.ts +26 -0
- package/dist/components/tooltip/index.js +50 -0
- package/dist/components/tree-view/index.d.ts +37 -0
- package/dist/components/tree-view/index.js +63 -0
- package/dist/components/wrap/index.d.ts +15 -0
- package/dist/components/wrap/index.js +5 -0
- package/dist/display-date-value-CdfgVuB7.d.ts +15 -0
- package/dist/display-date-value-gTlidtNz.js +21 -0
- package/dist/display-value-BNKxQ99u.js +37 -0
- package/dist/display-value-IyQT1429.d.ts +11 -0
- package/dist/featured-icon-DPysOpSf.js +35 -0
- package/dist/function-DOGwA2sm.js +7 -0
- package/dist/show-IaI-36v9.js +12 -0
- package/dist/span-DWZSA3mH.js +7 -0
- package/dist/types/index.d.ts +17 -0
- package/dist/types/index.js +0 -0
- package/dist/utils/index.d.ts +206 -0
- package/dist/utils/index.js +377 -0
- package/package.json +89 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { ark } from "@ark-ui/react/factory";
|
|
2
|
+
import { styled } from "@pyck/styled-system/jsx";
|
|
3
|
+
import { icon } from "@pyck/styled-system/recipes";
|
|
4
|
+
import { cva } from "@pyck/styled-system/css";
|
|
5
|
+
|
|
6
|
+
//#region src/components/icon/icon.tsx
|
|
7
|
+
const Icon = styled(ark.svg, icon, { defaultProps: { asChild: true } });
|
|
8
|
+
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/components/icon/featured-icon.tsx
|
|
11
|
+
const IconWrapper = styled("div", cva({
|
|
12
|
+
base: {
|
|
13
|
+
alignItems: "center",
|
|
14
|
+
background: "gray.surface.bg",
|
|
15
|
+
borderWidth: "1px",
|
|
16
|
+
boxSize: "12",
|
|
17
|
+
color: "gray.surface.fg",
|
|
18
|
+
display: "flex",
|
|
19
|
+
justifyContent: "center"
|
|
20
|
+
},
|
|
21
|
+
variants: { variant: { embedded: {
|
|
22
|
+
boxSize: "49px",
|
|
23
|
+
color: "gray.surface.fg/80",
|
|
24
|
+
transform: "translate(-1px, -1px)"
|
|
25
|
+
} } }
|
|
26
|
+
}));
|
|
27
|
+
const FeaturedIcon = (props) => {
|
|
28
|
+
const { children, ...rest } = props;
|
|
29
|
+
return <IconWrapper {...rest}>
|
|
30
|
+
<Icon>{children}</Icon>
|
|
31
|
+
</IconWrapper>;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
//#endregion
|
|
35
|
+
export { Icon as n, FeaturedIcon as t };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
//#region src/utils/function.ts
|
|
2
|
+
const isFunction = (v) => typeof v === "function";
|
|
3
|
+
const isString = (v) => typeof v === "string";
|
|
4
|
+
const runIfFn = (valueOrFn, ...args) => isFunction(valueOrFn) ? valueOrFn(...args) : valueOrFn;
|
|
5
|
+
|
|
6
|
+
//#endregion
|
|
7
|
+
export { isString as n, runIfFn as r, isFunction as t };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { isValidElement } from "react";
|
|
2
|
+
|
|
3
|
+
//#region src/components/show/show.tsx
|
|
4
|
+
function Show(props) {
|
|
5
|
+
const { when, fallback, children } = props;
|
|
6
|
+
if (!when) return fallback ?? null;
|
|
7
|
+
const result = typeof children === "function" ? children(when) : children;
|
|
8
|
+
return isValidElement(result) ? result : <>{result}</>;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
//#endregion
|
|
12
|
+
export { Show as t };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Optional } from "@ark-ui/react";
|
|
2
|
+
|
|
3
|
+
//#region src/types/index.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Extracts the element type from an array type T.
|
|
6
|
+
*/
|
|
7
|
+
type ElementType<T> = T extends (infer U)[] ? U : T;
|
|
8
|
+
/**
|
|
9
|
+
* A dictionary type with string keys and values of type T.
|
|
10
|
+
*/
|
|
11
|
+
type Dict<T = unknown> = Record<string, T>;
|
|
12
|
+
/**
|
|
13
|
+
* A type representing any function.
|
|
14
|
+
*/
|
|
15
|
+
type AnyFunction = (...args: never[]) => unknown;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { AnyFunction, Dict, ElementType, type Optional };
|
|
File without changes
|
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
import { GridCollection, createGridCollection, useAsyncList } from "@ark-ui/react/collection";
|
|
2
|
+
import { createContext } from "@ark-ui/react/utils";
|
|
3
|
+
import { useDebounce } from "ahooks";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { DateValue } from "@ark-ui/react/date-picker";
|
|
6
|
+
import * as react from "react";
|
|
7
|
+
import { Dispatch, EffectCallback, Ref, SetStateAction } from "react";
|
|
8
|
+
import { Dict } from "@pyck/react/types";
|
|
9
|
+
|
|
10
|
+
//#region src/utils/capitalize.d.ts
|
|
11
|
+
declare const capitalize: (s: string) => string;
|
|
12
|
+
//#endregion
|
|
13
|
+
//#region src/utils/compose-refs.d.ts
|
|
14
|
+
type PossibleRef<T> = Ref<T | null> | undefined;
|
|
15
|
+
declare function composeRefs<T>(...refs: PossibleRef<T>[]): (node: T | null) => void;
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/utils/data-attr.d.ts
|
|
18
|
+
declare const dataAttr: (condition: boolean | string | undefined | null) => string | undefined;
|
|
19
|
+
//#endregion
|
|
20
|
+
//#region src/utils/date-formatter.d.ts
|
|
21
|
+
type DateInput = string | Date | null | undefined;
|
|
22
|
+
type Locale = 'en-US' | 'en-GB' | 'de-DE';
|
|
23
|
+
declare const getDateFormats: (locale: Locale) => {
|
|
24
|
+
SHORT_DATE: string;
|
|
25
|
+
LONG_DATE: string;
|
|
26
|
+
TIME: string;
|
|
27
|
+
TIME_12H: string;
|
|
28
|
+
DATETIME: string;
|
|
29
|
+
MONTH_DAY: string;
|
|
30
|
+
DAY_YEAR: string;
|
|
31
|
+
};
|
|
32
|
+
declare function formatDate(date: DateInput, formatStr?: string, locale?: Locale): string | null | undefined;
|
|
33
|
+
declare function formatDateTime(date: DateInput, type?: 'date' | 'time' | 'datetime' | 'relative', locale?: Locale): string | null | undefined;
|
|
34
|
+
declare function formatDateRange(start: DateInput, end: DateInput, locale?: Locale): string | null | undefined;
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/utils/function.d.ts
|
|
37
|
+
declare const isFunction: <T extends (...args: never[]) => unknown>(v: unknown) => v is T;
|
|
38
|
+
declare const isString: (v: unknown) => v is string;
|
|
39
|
+
declare const runIfFn: <T, Args extends unknown[]>(valueOrFn: T | ((...args: Args) => T), ...args: Args) => T;
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/utils/is-empty.d.ts
|
|
42
|
+
declare const isEmpty: <T>(value: string | null | undefined | T[] | readonly T[]) => value is null | undefined | "";
|
|
43
|
+
declare const isNotEmpty: <T>(value: string | null | undefined | T[] | readonly T[]) => value is string | T[];
|
|
44
|
+
//#endregion
|
|
45
|
+
//#region src/utils/json-schema.d.ts
|
|
46
|
+
type StringSchema = {
|
|
47
|
+
type: 'string';
|
|
48
|
+
title?: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
enum?: readonly string[];
|
|
51
|
+
minLength?: number;
|
|
52
|
+
maxLength?: number;
|
|
53
|
+
format?: 'email' | 'date' | 'date-time';
|
|
54
|
+
};
|
|
55
|
+
type NumberSchema = {
|
|
56
|
+
type: 'number';
|
|
57
|
+
title?: string;
|
|
58
|
+
description?: string;
|
|
59
|
+
format?: 'currency';
|
|
60
|
+
minimum?: number;
|
|
61
|
+
maximum?: number;
|
|
62
|
+
};
|
|
63
|
+
type IntegerSchema = {
|
|
64
|
+
type: 'integer';
|
|
65
|
+
title?: string;
|
|
66
|
+
description?: string;
|
|
67
|
+
minimum?: number;
|
|
68
|
+
maximum?: number;
|
|
69
|
+
};
|
|
70
|
+
type BooleanSchema = {
|
|
71
|
+
type: 'boolean';
|
|
72
|
+
title?: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
};
|
|
75
|
+
type ArraySchema = {
|
|
76
|
+
type: 'array';
|
|
77
|
+
title?: string;
|
|
78
|
+
description?: string;
|
|
79
|
+
items: JsonSchema;
|
|
80
|
+
minItems?: number;
|
|
81
|
+
maxItems?: number;
|
|
82
|
+
};
|
|
83
|
+
type ObjectSchema = {
|
|
84
|
+
type: 'object';
|
|
85
|
+
title?: string;
|
|
86
|
+
description?: string;
|
|
87
|
+
properties?: Record<string, JsonSchema>;
|
|
88
|
+
required?: string[];
|
|
89
|
+
additionalProperties?: boolean | JsonSchema;
|
|
90
|
+
};
|
|
91
|
+
type JsonSchema = StringSchema | NumberSchema | IntegerSchema | BooleanSchema | ArraySchema | ObjectSchema;
|
|
92
|
+
declare const jsonSchema: z.ZodType<JsonSchema>;
|
|
93
|
+
interface FieldDefinitionBase<TValue, TSchema extends JsonSchema> {
|
|
94
|
+
value: TValue;
|
|
95
|
+
schema: TSchema;
|
|
96
|
+
required?: boolean;
|
|
97
|
+
}
|
|
98
|
+
type FieldDefinition = FieldDefinitionBase<string, StringSchema> | FieldDefinitionBase<number, NumberSchema> | FieldDefinitionBase<number, IntegerSchema> | FieldDefinitionBase<boolean, BooleanSchema> | FieldDefinitionBase<unknown, ArraySchema> | FieldDefinitionBase<unknown, ObjectSchema>;
|
|
99
|
+
type FieldDefinitions = Record<string, FieldDefinition>;
|
|
100
|
+
declare const createFieldDefinition: (schema: JsonSchema, value: unknown, required?: boolean) => FieldDefinition;
|
|
101
|
+
declare const createFieldDefinitions: (schema: JsonSchema, data: Dict) => FieldDefinitions;
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region src/utils/json-schema-types.d.ts
|
|
104
|
+
/**
|
|
105
|
+
* JSON Schema type definitions
|
|
106
|
+
* Based on JSON Schema Draft 7 specification
|
|
107
|
+
*/
|
|
108
|
+
interface JSONSchemaProperty {
|
|
109
|
+
type?: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'null';
|
|
110
|
+
enum?: string[];
|
|
111
|
+
properties?: Record<string, JSONSchemaProperty>;
|
|
112
|
+
items?: JSONSchemaProperty;
|
|
113
|
+
required?: string[];
|
|
114
|
+
description?: string;
|
|
115
|
+
title?: string;
|
|
116
|
+
format?: 'date' | 'date-time' | 'time' | 'email' | 'uuid' | 'uri' | 'ipv4' | 'ipv6';
|
|
117
|
+
default?: unknown;
|
|
118
|
+
minLength?: number;
|
|
119
|
+
maxLength?: number;
|
|
120
|
+
minimum?: number;
|
|
121
|
+
maximum?: number;
|
|
122
|
+
pattern?: string;
|
|
123
|
+
minItems?: number;
|
|
124
|
+
maxItems?: number;
|
|
125
|
+
uniqueItems?: boolean;
|
|
126
|
+
}
|
|
127
|
+
interface JSONSchema {
|
|
128
|
+
type?: 'object';
|
|
129
|
+
properties?: Record<string, JSONSchemaProperty>;
|
|
130
|
+
required?: string[];
|
|
131
|
+
title?: string;
|
|
132
|
+
description?: string;
|
|
133
|
+
additionalProperties?: boolean | JSONSchemaProperty;
|
|
134
|
+
}
|
|
135
|
+
//#endregion
|
|
136
|
+
//#region src/utils/omit.d.ts
|
|
137
|
+
declare const omit: <T extends object, K extends keyof T>(object: T, keysToOmit?: readonly K[]) => Omit<T, K>;
|
|
138
|
+
//#endregion
|
|
139
|
+
//#region src/utils/parse-date.d.ts
|
|
140
|
+
/**
|
|
141
|
+
* Custom parseDate wrapper that handles our timestamp formats
|
|
142
|
+
*
|
|
143
|
+
* Ark UI's parseDate only accepts:
|
|
144
|
+
* - Date objects
|
|
145
|
+
* - Date-only strings: "2024-11-25"
|
|
146
|
+
* - NOT timestamps with time components
|
|
147
|
+
*
|
|
148
|
+
* This utility handles:
|
|
149
|
+
* - Date objects
|
|
150
|
+
* - ISO date strings: "2024-11-25"
|
|
151
|
+
* - Timestamps: "2024-11-25T15:17:45Z" (extracts date part)
|
|
152
|
+
* - Timestamps with milliseconds: "2024-11-25T15:17:45.000Z" (extracts date part)
|
|
153
|
+
*
|
|
154
|
+
* @param value - The date value to parse (string or Date)
|
|
155
|
+
* @returns DateValue object compatible with Ark UI date picker
|
|
156
|
+
* @throws Error if the value cannot be parsed
|
|
157
|
+
*/
|
|
158
|
+
declare function parseDate(value: string | Date): DateValue;
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/utils/partition.d.ts
|
|
161
|
+
declare const partition: <T>(arr: T[], predicate: (item: T) => boolean) => [T[], T[]];
|
|
162
|
+
//#endregion
|
|
163
|
+
//#region src/utils/use-auto-focus.d.ts
|
|
164
|
+
declare const useAutoFocus: (shouldFocus?: boolean) => react.RefObject<HTMLInputElement | null>;
|
|
165
|
+
//#endregion
|
|
166
|
+
//#region src/utils/use-effect-once.d.ts
|
|
167
|
+
declare const useEffectOnce: (cb: EffectCallback) => void;
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/utils/use-history-state.d.ts
|
|
170
|
+
/**
|
|
171
|
+
* Configuration options for the useHistoryState hook.
|
|
172
|
+
*/
|
|
173
|
+
interface HistoryStateOptions {
|
|
174
|
+
/**
|
|
175
|
+
* Maximum number of history entries to keep.
|
|
176
|
+
* When exceeded, oldest entries are removed.
|
|
177
|
+
* @default 10
|
|
178
|
+
*/
|
|
179
|
+
limit?: number;
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* A React hook that provides state management with undo/redo history.
|
|
183
|
+
*
|
|
184
|
+
* @template T - The type of the state value
|
|
185
|
+
* @param options - Configuration options for the history state
|
|
186
|
+
*
|
|
187
|
+
* @returns An object containing the current state, setState function, and undo/redo controls
|
|
188
|
+
*
|
|
189
|
+
* @example
|
|
190
|
+
* ```tsx
|
|
191
|
+
* const { state, setState, undo, redo, canUndo, canRedo } = useHistoryState(0, { limit: 50 })
|
|
192
|
+
* ```
|
|
193
|
+
*/
|
|
194
|
+
declare function useHistoryState<T>(initialValue: T, options?: HistoryStateOptions): {
|
|
195
|
+
state: T;
|
|
196
|
+
setState: Dispatch<SetStateAction<T>>;
|
|
197
|
+
canUndo: () => boolean;
|
|
198
|
+
undo: () => void;
|
|
199
|
+
canRedo: () => boolean;
|
|
200
|
+
redo: () => void;
|
|
201
|
+
};
|
|
202
|
+
//#endregion
|
|
203
|
+
//#region src/utils/use-hotkey.d.ts
|
|
204
|
+
declare const useHotkey: (setOpen: (open: boolean) => void) => void;
|
|
205
|
+
//#endregion
|
|
206
|
+
export { type DateInput, type FieldDefinition, type GridCollection, type JSONSchema, type JSONSchemaProperty, type JsonSchema, type Locale, capitalize, composeRefs, createContext, createFieldDefinition, createFieldDefinitions, createGridCollection, dataAttr, formatDate, formatDateRange, formatDateTime, getDateFormats, isEmpty, isFunction, isNotEmpty, isString, jsonSchema, omit, parseDate, partition, runIfFn, useAsyncList, useAutoFocus, useDebounce, useEffectOnce, useHistoryState, useHotkey };
|
|
@@ -0,0 +1,377 @@
|
|
|
1
|
+
import { n as isString, r as runIfFn, t as isFunction } from "../function-DOGwA2sm.js";
|
|
2
|
+
import { createGridCollection, useAsyncList } from "@ark-ui/react/collection";
|
|
3
|
+
import { createContext } from "@ark-ui/react/utils";
|
|
4
|
+
import { useDebounce } from "ahooks";
|
|
5
|
+
import { format, isToday, isValid, parseISO } from "date-fns";
|
|
6
|
+
import { de, enGB, enUS } from "date-fns/locale";
|
|
7
|
+
import { match } from "ts-pattern";
|
|
8
|
+
import { z } from "zod";
|
|
9
|
+
import { parseDate as parseDate$1 } from "@ark-ui/react/date-picker";
|
|
10
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
11
|
+
import { useEnvironmentContext } from "@ark-ui/react/environment";
|
|
12
|
+
|
|
13
|
+
//#region src/utils/capitalize.ts
|
|
14
|
+
const capitalize = (s) => s.charAt(0).toUpperCase() + s.slice(1);
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/utils/compose-refs.ts
|
|
18
|
+
function composeRefs(...refs) {
|
|
19
|
+
return (node) => {
|
|
20
|
+
const cleanUps = [];
|
|
21
|
+
for (const ref of refs) if (typeof ref === "function") {
|
|
22
|
+
const cb = ref(node);
|
|
23
|
+
if (typeof cb === "function") cleanUps.push(cb);
|
|
24
|
+
} else if (ref) ref.current = node;
|
|
25
|
+
if (cleanUps.length) return () => {
|
|
26
|
+
for (const cleanUp of cleanUps) cleanUp();
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region src/utils/data-attr.ts
|
|
33
|
+
const dataAttr = (condition) => {
|
|
34
|
+
if (!condition && condition !== "") return void 0;
|
|
35
|
+
return isString(condition) ? condition : "";
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
//#endregion
|
|
39
|
+
//#region src/utils/date-formatter.ts
|
|
40
|
+
const DEFAULT_LOCALE = "en-US";
|
|
41
|
+
const localeMap = {
|
|
42
|
+
"en-US": enUS,
|
|
43
|
+
"en-GB": enGB,
|
|
44
|
+
"de-DE": de
|
|
45
|
+
};
|
|
46
|
+
const getDateFormats = (locale) => {
|
|
47
|
+
return match(locale).with("en-US", () => ({
|
|
48
|
+
SHORT_DATE: "MMM d, yyyy",
|
|
49
|
+
LONG_DATE: "MMM dd, yyyy",
|
|
50
|
+
TIME: "HH:mm",
|
|
51
|
+
TIME_12H: "h:mma",
|
|
52
|
+
DATETIME: "MMM dd, yyyy HH:mm",
|
|
53
|
+
MONTH_DAY: "MMM d",
|
|
54
|
+
DAY_YEAR: "d, yyyy"
|
|
55
|
+
})).with("en-GB", () => ({
|
|
56
|
+
SHORT_DATE: "d MMM yyyy",
|
|
57
|
+
LONG_DATE: "dd MMM yyyy",
|
|
58
|
+
TIME: "HH:mm",
|
|
59
|
+
TIME_12H: "h:mma",
|
|
60
|
+
DATETIME: "dd MMM yyyy HH:mm",
|
|
61
|
+
MONTH_DAY: "d MMM",
|
|
62
|
+
DAY_YEAR: "d, yyyy"
|
|
63
|
+
})).with("de-DE", () => ({
|
|
64
|
+
SHORT_DATE: "d. MMM yyyy",
|
|
65
|
+
LONG_DATE: "dd. MMM yyyy",
|
|
66
|
+
TIME: "HH:mm",
|
|
67
|
+
TIME_12H: "HH:mm",
|
|
68
|
+
DATETIME: "dd. MMM yyyy HH:mm",
|
|
69
|
+
MONTH_DAY: "d. MMM",
|
|
70
|
+
DAY_YEAR: "d, yyyy"
|
|
71
|
+
})).exhaustive();
|
|
72
|
+
};
|
|
73
|
+
function formatDate(date, formatStr, locale = DEFAULT_LOCALE) {
|
|
74
|
+
if (!date) return date === null ? null : void 0;
|
|
75
|
+
const dateObj = date instanceof Date ? date : parseISO(date);
|
|
76
|
+
if (!isValid(dateObj)) return null;
|
|
77
|
+
const dateFormats = getDateFormats(locale);
|
|
78
|
+
return format(dateObj, formatStr || dateFormats.LONG_DATE, { locale: localeMap[locale] });
|
|
79
|
+
}
|
|
80
|
+
function formatDateTime(date, type = "date", locale = DEFAULT_LOCALE) {
|
|
81
|
+
if (!date) return date === null ? null : void 0;
|
|
82
|
+
const dateObj = date instanceof Date ? date : parseISO(date);
|
|
83
|
+
if (!isValid(dateObj)) return null;
|
|
84
|
+
const dateFormats = getDateFormats(locale);
|
|
85
|
+
const localeObj = localeMap[locale];
|
|
86
|
+
return match(type).with("time", () => format(dateObj, dateFormats.TIME, { locale: localeObj })).with("datetime", () => format(dateObj, dateFormats.DATETIME, { locale: localeObj })).with("relative", () => {
|
|
87
|
+
if (isToday(dateObj)) return format(dateObj, dateFormats.TIME, { locale: localeObj });
|
|
88
|
+
return format(dateObj, dateFormats.LONG_DATE, { locale: localeObj });
|
|
89
|
+
}).with("date", () => format(dateObj, dateFormats.LONG_DATE, { locale: localeObj })).exhaustive();
|
|
90
|
+
}
|
|
91
|
+
function formatDateRange(start, end, locale = DEFAULT_LOCALE) {
|
|
92
|
+
if (!start || !end) return start === null || end === null ? null : void 0;
|
|
93
|
+
const startDate = start instanceof Date ? start : parseISO(start);
|
|
94
|
+
const endDate = end instanceof Date ? end : parseISO(end);
|
|
95
|
+
if (!isValid(startDate) || !isValid(endDate)) return null;
|
|
96
|
+
const dateFormats = getDateFormats(locale);
|
|
97
|
+
const localeObj = localeMap[locale];
|
|
98
|
+
const sameYear = startDate.getFullYear() === endDate.getFullYear();
|
|
99
|
+
const sameMonth = sameYear && startDate.getMonth() === endDate.getMonth();
|
|
100
|
+
const startFormat = sameMonth ? dateFormats.MONTH_DAY : sameYear ? dateFormats.MONTH_DAY : dateFormats.SHORT_DATE;
|
|
101
|
+
const endFormat = sameMonth ? dateFormats.DAY_YEAR : dateFormats.SHORT_DATE;
|
|
102
|
+
return `${format(startDate, startFormat, { locale: localeObj })} – ${format(endDate, endFormat, { locale: localeObj })}`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
//#endregion
|
|
106
|
+
//#region src/utils/is-empty.ts
|
|
107
|
+
const isEmpty = (value) => {
|
|
108
|
+
if (value == null) return true;
|
|
109
|
+
if (isString(value)) return value.trim().length === 0;
|
|
110
|
+
if (Array.isArray(value)) return value.length === 0;
|
|
111
|
+
return false;
|
|
112
|
+
};
|
|
113
|
+
const isNotEmpty = (value) => {
|
|
114
|
+
return !isEmpty(value);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
//#endregion
|
|
118
|
+
//#region src/utils/json-schema.ts
|
|
119
|
+
const jsonSchema = z.lazy(() => jsonSchemaUnion);
|
|
120
|
+
const stringSchema = z.object({
|
|
121
|
+
type: z.literal("string"),
|
|
122
|
+
title: z.string().optional(),
|
|
123
|
+
description: z.string().optional(),
|
|
124
|
+
enum: z.array(z.string()).readonly().optional(),
|
|
125
|
+
minLength: z.number().optional(),
|
|
126
|
+
maxLength: z.number().optional(),
|
|
127
|
+
format: z.enum([
|
|
128
|
+
"email",
|
|
129
|
+
"date",
|
|
130
|
+
"date-time"
|
|
131
|
+
]).optional()
|
|
132
|
+
}).strict();
|
|
133
|
+
const numberSchema = z.object({
|
|
134
|
+
type: z.literal("number"),
|
|
135
|
+
title: z.string().optional(),
|
|
136
|
+
description: z.string().optional(),
|
|
137
|
+
format: z.enum(["currency"]).optional(),
|
|
138
|
+
minimum: z.number().optional(),
|
|
139
|
+
maximum: z.number().optional()
|
|
140
|
+
}).strict();
|
|
141
|
+
const integerSchema = z.object({
|
|
142
|
+
type: z.literal("integer"),
|
|
143
|
+
title: z.string().optional(),
|
|
144
|
+
description: z.string().optional(),
|
|
145
|
+
minimum: z.number().optional(),
|
|
146
|
+
maximum: z.number().optional()
|
|
147
|
+
}).strict();
|
|
148
|
+
const booleanSchema = z.object({
|
|
149
|
+
type: z.literal("boolean"),
|
|
150
|
+
title: z.string().optional(),
|
|
151
|
+
description: z.string().optional()
|
|
152
|
+
}).strict();
|
|
153
|
+
const arraySchema = z.object({
|
|
154
|
+
type: z.literal("array"),
|
|
155
|
+
title: z.string().optional(),
|
|
156
|
+
description: z.string().optional(),
|
|
157
|
+
items: jsonSchema,
|
|
158
|
+
minItems: z.number().optional(),
|
|
159
|
+
maxItems: z.number().optional()
|
|
160
|
+
}).strict();
|
|
161
|
+
const objectSchema = z.object({
|
|
162
|
+
type: z.literal("object"),
|
|
163
|
+
title: z.string().optional(),
|
|
164
|
+
description: z.string().optional(),
|
|
165
|
+
properties: z.record(z.string(), jsonSchema).optional(),
|
|
166
|
+
required: z.array(z.string()).optional(),
|
|
167
|
+
additionalProperties: z.union([z.boolean(), jsonSchema]).optional()
|
|
168
|
+
}).strict();
|
|
169
|
+
const jsonSchemaUnion = z.union([
|
|
170
|
+
stringSchema,
|
|
171
|
+
numberSchema,
|
|
172
|
+
integerSchema,
|
|
173
|
+
booleanSchema,
|
|
174
|
+
arraySchema,
|
|
175
|
+
objectSchema
|
|
176
|
+
]);
|
|
177
|
+
const createFieldDefinition = (schema, value, required) => match(schema).with({ type: "string" }, (s) => ({
|
|
178
|
+
schema: s,
|
|
179
|
+
value,
|
|
180
|
+
required
|
|
181
|
+
})).with({ type: "number" }, (s) => ({
|
|
182
|
+
schema: s,
|
|
183
|
+
value,
|
|
184
|
+
required
|
|
185
|
+
})).with({ type: "integer" }, (s) => ({
|
|
186
|
+
schema: s,
|
|
187
|
+
value,
|
|
188
|
+
required
|
|
189
|
+
})).with({ type: "boolean" }, (s) => ({
|
|
190
|
+
schema: s,
|
|
191
|
+
value,
|
|
192
|
+
required
|
|
193
|
+
})).with({ type: "array" }, (s) => ({
|
|
194
|
+
schema: s,
|
|
195
|
+
value,
|
|
196
|
+
required
|
|
197
|
+
})).with({ type: "object" }, (s) => ({
|
|
198
|
+
schema: s,
|
|
199
|
+
value,
|
|
200
|
+
required
|
|
201
|
+
})).exhaustive();
|
|
202
|
+
const createFieldDefinitions = (schema, data) => {
|
|
203
|
+
if (schema.type !== "object" || !schema.properties) throw new Error("Schema must be an object type with properties");
|
|
204
|
+
const required = new Set(schema.required);
|
|
205
|
+
return Object.fromEntries(Object.entries(schema.properties).map(([key, s]) => [key, createFieldDefinition(s, data[key], required.has(key))]));
|
|
206
|
+
};
|
|
207
|
+
|
|
208
|
+
//#endregion
|
|
209
|
+
//#region src/utils/omit.ts
|
|
210
|
+
const omit = (object, keysToOmit = []) => Object.fromEntries(Object.entries(object).filter(([key]) => !keysToOmit.includes(key)));
|
|
211
|
+
|
|
212
|
+
//#endregion
|
|
213
|
+
//#region src/utils/parse-date.ts
|
|
214
|
+
/**
|
|
215
|
+
* Custom parseDate wrapper that handles our timestamp formats
|
|
216
|
+
*
|
|
217
|
+
* Ark UI's parseDate only accepts:
|
|
218
|
+
* - Date objects
|
|
219
|
+
* - Date-only strings: "2024-11-25"
|
|
220
|
+
* - NOT timestamps with time components
|
|
221
|
+
*
|
|
222
|
+
* This utility handles:
|
|
223
|
+
* - Date objects
|
|
224
|
+
* - ISO date strings: "2024-11-25"
|
|
225
|
+
* - Timestamps: "2024-11-25T15:17:45Z" (extracts date part)
|
|
226
|
+
* - Timestamps with milliseconds: "2024-11-25T15:17:45.000Z" (extracts date part)
|
|
227
|
+
*
|
|
228
|
+
* @param value - The date value to parse (string or Date)
|
|
229
|
+
* @returns DateValue object compatible with Ark UI date picker
|
|
230
|
+
* @throws Error if the value cannot be parsed
|
|
231
|
+
*/
|
|
232
|
+
function parseDate(value) {
|
|
233
|
+
if (value instanceof Date) return parseDate$1(value);
|
|
234
|
+
if (typeof value !== "string") throw new Error(`Invalid date value type: ${typeof value}`);
|
|
235
|
+
try {
|
|
236
|
+
return parseDate$1(value);
|
|
237
|
+
} catch {
|
|
238
|
+
const dateOnlyMatch = value.match(/^(\d{4}-\d{2}-\d{2})/);
|
|
239
|
+
if (dateOnlyMatch?.[1]) return parseDate$1(dateOnlyMatch[1]);
|
|
240
|
+
try {
|
|
241
|
+
const date = new Date(value);
|
|
242
|
+
if (!Number.isNaN(date.getTime())) return parseDate$1(date);
|
|
243
|
+
} catch (error) {
|
|
244
|
+
console.debug("Failed to parse date as Date object:", error);
|
|
245
|
+
}
|
|
246
|
+
throw new Error(`Cannot parse date value: ${value}`);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
//#endregion
|
|
251
|
+
//#region src/utils/partition.ts
|
|
252
|
+
const partition = (arr, predicate) => arr.reduce(([pass, fail], item) => predicate(item) ? [[...pass, item], fail] : [pass, [...fail, item]], [[], []]);
|
|
253
|
+
|
|
254
|
+
//#endregion
|
|
255
|
+
//#region src/utils/use-auto-focus.ts
|
|
256
|
+
const useAutoFocus = (shouldFocus = true) => {
|
|
257
|
+
const ref = useRef(null);
|
|
258
|
+
useEffect(() => {
|
|
259
|
+
if (shouldFocus) setTimeout(() => {
|
|
260
|
+
ref.current?.focus();
|
|
261
|
+
}, 0);
|
|
262
|
+
}, [shouldFocus]);
|
|
263
|
+
return ref;
|
|
264
|
+
};
|
|
265
|
+
|
|
266
|
+
//#endregion
|
|
267
|
+
//#region src/utils/use-effect-once.ts
|
|
268
|
+
const useEffectOnce = (cb) => {
|
|
269
|
+
const savedCallback = useRef(cb);
|
|
270
|
+
const effectGuard = useRef(false);
|
|
271
|
+
useEffect(() => {
|
|
272
|
+
savedCallback.current = cb;
|
|
273
|
+
});
|
|
274
|
+
useEffect(() => {
|
|
275
|
+
if (effectGuard.current !== true) {
|
|
276
|
+
effectGuard.current = true;
|
|
277
|
+
savedCallback.current();
|
|
278
|
+
}
|
|
279
|
+
}, []);
|
|
280
|
+
};
|
|
281
|
+
|
|
282
|
+
//#endregion
|
|
283
|
+
//#region src/utils/use-history-state.ts
|
|
284
|
+
function isSetStateFunction(value) {
|
|
285
|
+
return typeof value === "function";
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* A React hook that provides state management with undo/redo history.
|
|
289
|
+
*
|
|
290
|
+
* @template T - The type of the state value
|
|
291
|
+
* @param options - Configuration options for the history state
|
|
292
|
+
*
|
|
293
|
+
* @returns An object containing the current state, setState function, and undo/redo controls
|
|
294
|
+
*
|
|
295
|
+
* @example
|
|
296
|
+
* ```tsx
|
|
297
|
+
* const { state, setState, undo, redo, canUndo, canRedo } = useHistoryState(0, { limit: 50 })
|
|
298
|
+
* ```
|
|
299
|
+
*/
|
|
300
|
+
function useHistoryState(initialValue, options) {
|
|
301
|
+
const limit = options?.limit ?? 10;
|
|
302
|
+
const [{ history, index }, setHistoryState] = useState({
|
|
303
|
+
history: [initialValue],
|
|
304
|
+
index: 0
|
|
305
|
+
});
|
|
306
|
+
if (index >= history.length || index < 0) throw Error(`Impossible State reached: ${index} | ${history.length}`);
|
|
307
|
+
const state = history[index];
|
|
308
|
+
/**
|
|
309
|
+
* Sets a new state value and adds it to the history.
|
|
310
|
+
* If called after undo operations, discards any "future" states.
|
|
311
|
+
*/
|
|
312
|
+
const setState = (setStateFnOrValue) => setHistoryState((prev) => {
|
|
313
|
+
const currentState = prev.history[prev.index];
|
|
314
|
+
const newState = isSetStateFunction(setStateFnOrValue) ? setStateFnOrValue(currentState) : setStateFnOrValue;
|
|
315
|
+
if (prev.index !== prev.history.length - 1) return {
|
|
316
|
+
history: [...prev.history.slice(0, prev.index + 1), newState],
|
|
317
|
+
index: prev.index + 1
|
|
318
|
+
};
|
|
319
|
+
if (prev.history.length >= limit) return {
|
|
320
|
+
history: [...prev.history.slice(1), newState],
|
|
321
|
+
index: prev.index
|
|
322
|
+
};
|
|
323
|
+
return {
|
|
324
|
+
history: [...prev.history, newState],
|
|
325
|
+
index: prev.index + 1
|
|
326
|
+
};
|
|
327
|
+
});
|
|
328
|
+
/**
|
|
329
|
+
* Returns whether there are previous states available to undo to.
|
|
330
|
+
*/
|
|
331
|
+
const canUndo = useCallback(() => index > 0, [index]);
|
|
332
|
+
/**
|
|
333
|
+
* Returns whether there are future states available to redo to.
|
|
334
|
+
*/
|
|
335
|
+
const canRedo = useCallback(() => index < history.length - 1, [index, history.length]);
|
|
336
|
+
return {
|
|
337
|
+
state,
|
|
338
|
+
setState,
|
|
339
|
+
canUndo,
|
|
340
|
+
undo: useCallback(() => {
|
|
341
|
+
setHistoryState((prev) => ({
|
|
342
|
+
...prev,
|
|
343
|
+
index: Math.max(0, prev.index - 1)
|
|
344
|
+
}));
|
|
345
|
+
}, []),
|
|
346
|
+
canRedo,
|
|
347
|
+
redo: useCallback(() => {
|
|
348
|
+
setHistoryState((prev) => ({
|
|
349
|
+
...prev,
|
|
350
|
+
index: Math.min(prev.history.length - 1, prev.index + 1)
|
|
351
|
+
}));
|
|
352
|
+
}, [])
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
//#endregion
|
|
357
|
+
//#region src/utils/use-hotkey.ts
|
|
358
|
+
const useHotkey = (setOpen) => {
|
|
359
|
+
const env = useEnvironmentContext();
|
|
360
|
+
useEffect(() => {
|
|
361
|
+
const document = env.getDocument();
|
|
362
|
+
const hotkey = /(Mac|iPhone|iPod|iPad)/i.test(navigator?.platform) ? "metaKey" : "ctrlKey";
|
|
363
|
+
const handleKeydown = (event) => {
|
|
364
|
+
if (event.key?.toLowerCase() === "k" && event[hotkey]) {
|
|
365
|
+
event.preventDefault();
|
|
366
|
+
setOpen(true);
|
|
367
|
+
}
|
|
368
|
+
};
|
|
369
|
+
document.addEventListener("keydown", handleKeydown, true);
|
|
370
|
+
return () => {
|
|
371
|
+
document.removeEventListener("keydown", handleKeydown, true);
|
|
372
|
+
};
|
|
373
|
+
}, [env, setOpen]);
|
|
374
|
+
};
|
|
375
|
+
|
|
376
|
+
//#endregion
|
|
377
|
+
export { capitalize, composeRefs, createContext, createFieldDefinition, createFieldDefinitions, createGridCollection, dataAttr, formatDate, formatDateRange, formatDateTime, getDateFormats, isEmpty, isFunction, isNotEmpty, isString, jsonSchema, omit, parseDate, partition, runIfFn, useAsyncList, useAutoFocus, useDebounce, useEffectOnce, useHistoryState, useHotkey };
|