@midseelee/date-fns-buddhist-adapter 1.0.0

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=adapters.js.map
@@ -0,0 +1,229 @@
1
+ import type { TextFieldProps } from '@mui/material/TextField';
2
+ import type * as React from 'react';
3
+ export interface FieldChangeHandlerContext<TError> {
4
+ validationError: TError;
5
+ }
6
+ export type FieldChangeHandler<TValue, TError> = (value: TValue, context: FieldChangeHandlerContext<TError>) => void;
7
+ export interface UseFieldInternalProps<TValue, TDate, TSection extends FieldSection, TError> {
8
+ /**
9
+ * The selected value.
10
+ * Used when the component is controlled.
11
+ */
12
+ value?: TValue;
13
+ /**
14
+ * The default value. Use when the component is not controlled.
15
+ */
16
+ defaultValue?: TValue;
17
+ /**
18
+ * The date used to generate a part of the new value that is not present in the format when both `value` and `defaultValue` are empty.
19
+ * For example, on time fields it will be used to determine the date to set.
20
+ * @default The closest valid date using the validation props, except callbacks such as `shouldDisableDate`. Value is rounded to the most granular section used.
21
+ */
22
+ referenceDate?: TDate;
23
+ /**
24
+ * Callback fired when the value changes.
25
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
26
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
27
+ * @param {TValue} value The new value.
28
+ * @param {FieldChangeHandlerContext<TError>} context The context containing the validation result of the current value.
29
+ */
30
+ onChange?: FieldChangeHandler<TValue, TError>;
31
+ /**
32
+ * Callback fired when the error associated to the current value changes.
33
+ * @template TValue The value type. Will be either the same type as `value` or `null`. Can be in `[start, end]` format in case of range value.
34
+ * @template TError The validation error type. Will be either `string` or a `null`. Can be in `[start, end]` format in case of range value.
35
+ * @param {TError} error The new error.
36
+ * @param {TValue} value The value associated to the error.
37
+ */
38
+ onError?: (error: TError, value: TValue) => void;
39
+ /**
40
+ * Format of the date when rendered in the input(s).
41
+ */
42
+ format: string;
43
+ /**
44
+ * Density of the format when rendered in the input.
45
+ * Setting `formatDensity` to `"spacious"` will add a space before and after each `/`, `-` and `.` character.
46
+ * @default "dense"
47
+ */
48
+ formatDensity?: 'dense' | 'spacious';
49
+ /**
50
+ * If `true`, the format will respect the leading zeroes (e.g: on dayjs, the format `M/D/YYYY` will render `8/16/2018`)
51
+ * If `false`, the format will always add leading zeroes (e.g: on dayjs, the format `M/D/YYYY` will render `08/16/2018`)
52
+ *
53
+ * Warning n°1: Luxon is not able to respect the leading zeroes when using macro tokens (e.g: "DD"), so `shouldRespectLeadingZeros={true}` might lead to inconsistencies when using `AdapterLuxon`.
54
+ *
55
+ * Warning n°2: When `shouldRespectLeadingZeros={true}`, the field will add an invisible character on the sections containing a single digit to make sure `onChange` is fired.
56
+ * If you need to get the clean value from the input, you can remove this character using `input.value.replace(/\u200e/g, '')`.
57
+ *
58
+ * Warning n°3: When used in strict mode, dayjs and moment require to respect the leading zeros.
59
+ * This mean that when using `shouldRespectLeadingZeros={false}`, if you retrieve the value directly from the input (not listening to `onChange`) and your format contains tokens without leading zeros, the value will not be parsed by your library.
60
+ *
61
+ * @default `false`
62
+ */
63
+ shouldRespectLeadingZeros?: boolean;
64
+ /**
65
+ * It prevents the user from changing the value of the field
66
+ * (not from interacting with the field).
67
+ * @default false
68
+ */
69
+ readOnly?: boolean;
70
+ /**
71
+ * The currently selected sections.
72
+ * This prop accept four formats:
73
+ * 1. If a number is provided, the section at this index will be selected.
74
+ * 2. If an object with a `startIndex` and `endIndex` properties are provided, the sections between those two indexes will be selected.
75
+ * 3. If a string of type `FieldSectionType` is provided, the first section with that name will be selected.
76
+ * 4. If `null` is provided, no section will be selected
77
+ * If not provided, the selected sections will be handled internally.
78
+ */
79
+ selectedSections?: FieldSelectedSections;
80
+ /**
81
+ * Callback fired when the selected sections change.
82
+ * @param {FieldSelectedSections} newValue The new selected sections.
83
+ */
84
+ onSelectedSectionsChange?: (newValue: FieldSelectedSections) => void;
85
+ /**
86
+ * The ref object used to imperatively interact with the field.
87
+ */
88
+ unstableFieldRef?: React.Ref<FieldRef<TSection>>;
89
+ }
90
+ export interface BaseFieldProps<TValue, TDate, TSection extends FieldSection, TError> extends Omit<UseFieldInternalProps<TValue, TDate, TSection, TError>, 'format'> {
91
+ className?: string;
92
+ format?: string;
93
+ disabled?: boolean;
94
+ ref?: React.Ref<HTMLDivElement>;
95
+ }
96
+ export type FieldsTextFieldProps = Omit<TextFieldProps, 'autoComplete' | 'error' | 'maxRows' | 'minRows' | 'multiline' | 'placeholder' | 'rows' | 'select' | 'SelectProps' | 'type'>;
97
+ export type FieldSectionType = 'year' | 'month' | 'day' | 'weekDay' | 'hours' | 'minutes' | 'seconds' | 'meridiem';
98
+ export type FieldSectionContentType = 'digit' | 'digit-with-letter' | 'letter';
99
+ export type FieldValueType = 'date' | 'time' | 'date-time';
100
+ export interface FieldSection {
101
+ /**
102
+ * Value of the section, as rendered inside the input.
103
+ * For example, in the date `May 25, 1995`, the value of the month section is "May".
104
+ */
105
+ value: string;
106
+ /**
107
+ * Format token used to parse the value of this section from the date object.
108
+ * For example, in the format `MMMM D, YYYY`, the format of the month section is "MMMM".
109
+ */
110
+ format: string;
111
+ /**
112
+ * Maximum length of the value, only defined for "digit" sections.
113
+ * Will be used to determine how many leading zeros should be added to the value.
114
+ */
115
+ maxLength: number | null;
116
+ /**
117
+ * Placeholder rendered when the value of this section is empty.
118
+ */
119
+ placeholder: string;
120
+ /**
121
+ * Type of the section.
122
+ */
123
+ type: FieldSectionType;
124
+ /**
125
+ * Type of content of the section.
126
+ * Will determine if we should apply a digit-based editing or a letter-based editing.
127
+ */
128
+ contentType: FieldSectionContentType;
129
+ /**
130
+ * If `true`, the value of this section is supposed to have leading zeroes when parsed by the date library.
131
+ * For example, the value `1` should be rendered as "01" instead of "1".
132
+ * @deprecated Will be removed in v7, use `hasLeadingZerosInFormat` instead.
133
+ */
134
+ hasLeadingZeros: boolean;
135
+ /**
136
+ * If `true`, the value of this section is supposed to have leading zeroes when parsed by the date library.
137
+ * For example, the value `1` should be rendered as "01" instead of "1".
138
+ */
139
+ hasLeadingZerosInFormat: boolean;
140
+ /**
141
+ * If `true`, the value of this section is supposed to have leading zeroes when rendered in the input.
142
+ * For example, the value `1` should be rendered as "01" instead of "1".
143
+ */
144
+ hasLeadingZerosInInput: boolean;
145
+ /**
146
+ * If `true`, the section value has been modified since the last time the sections were generated from a valid date.
147
+ * When we can generate a valid date from the section, we don't directly pass it to `onChange`,
148
+ * Otherwise, we would lose all the information contained in the original date, things like:
149
+ * - time if the format does not contain it
150
+ * - timezone / UTC
151
+ *
152
+ * To avoid losing that information, we transfer the values of the modified sections from the newly generated date to the original date.
153
+ */
154
+ modified: boolean;
155
+ /**
156
+ * Start index of the section in the format
157
+ */
158
+ start: number;
159
+ /**
160
+ * End index of the section in the format
161
+ */
162
+ end: number;
163
+ /**
164
+ * Start index of the section value in the input.
165
+ * Takes into account invisible unicode characters such as \u2069 but does not include them
166
+ */
167
+ startInInput: number;
168
+ /**
169
+ * End index of the section value in the input.
170
+ * Takes into account invisible unicode characters such as \u2069 but does not include them
171
+ */
172
+ endInInput: number;
173
+ /**
174
+ * Separator displayed before the value of the section in the input.
175
+ * If it contains escaped characters, then it must not have the escaping characters.
176
+ * For example, on Day.js, the `year` section of the format `YYYY [year]` has an end separator equal to `year` not `[year]`
177
+ */
178
+ startSeparator: string;
179
+ /**
180
+ * Separator displayed after the value of the section in the input.
181
+ * If it contains escaped characters, then it must not have the escaping characters.
182
+ * For example, on Day.js, the `year` section of the format `[year] YYYY` has a start separator equal to `[year]`
183
+ */
184
+ endSeparator: string;
185
+ }
186
+ export interface FieldRef<TSection extends FieldSection> {
187
+ /**
188
+ * Returns the sections of the current value.
189
+ * @returns {TSection[]} The sections of the current value.
190
+ */
191
+ getSections: () => TSection[];
192
+ /**
193
+ * Returns the index of the active section (the first focused section).
194
+ * If no section is active, returns `null`.
195
+ * @returns {number | null} The index of the active section.
196
+ */
197
+ getActiveSectionIndex: () => number | null;
198
+ /**
199
+ * Updates the selected sections.
200
+ * @param {FieldSelectedSections} selectedSections The sections to select.
201
+ */
202
+ setSelectedSections: (selectedSections: FieldSelectedSections) => void;
203
+ }
204
+ export type FieldSelectedSections = number | FieldSectionType | null | 'all' | {
205
+ startIndex: number;
206
+ endIndex: number;
207
+ };
208
+ /**
209
+ * Props the single input field can receive when used inside a picker.
210
+ * Only contains what the MUI component are passing to the field, not what users can pass using the `props.slotProps.field`.
211
+ */
212
+ export interface BaseSingleInputFieldProps<TValue, TDate, TSection extends FieldSection, TError> extends BaseFieldProps<TValue, TDate, TSection, TError> {
213
+ label?: React.ReactNode;
214
+ id?: string;
215
+ inputRef?: React.Ref<HTMLInputElement>;
216
+ onKeyDown?: React.KeyboardEventHandler;
217
+ onBlur?: React.FocusEventHandler;
218
+ focused?: boolean;
219
+ InputProps?: {
220
+ ref?: React.Ref<any>;
221
+ endAdornment?: React.ReactNode;
222
+ startAdornment?: React.ReactNode;
223
+ };
224
+ inputProps?: {
225
+ 'aria-label'?: string;
226
+ };
227
+ slots?: Record<string, never>;
228
+ slotProps?: Record<string, never>;
229
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=fields.js.map
@@ -0,0 +1,3 @@
1
+ export * from './adapters';
2
+ export * from './fields';
3
+ export * from './timezone';
@@ -0,0 +1,4 @@
1
+ export * from './adapters';
2
+ export * from './fields';
3
+ export * from './timezone';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ export type PickersTimezone = 'default' | 'system' | 'UTC' | string;
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=timezone.js.map
package/jest.config.ts ADDED
@@ -0,0 +1,15 @@
1
+ import type { Config } from 'jest'
2
+
3
+ const config: Config = {
4
+ roots: ['<rootDir>/src'],
5
+ preset: 'ts-jest',
6
+ testEnvironment: 'node',
7
+ clearMocks: true,
8
+ collectCoverage: false,
9
+ collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'],
10
+ coverageDirectory: 'coverage',
11
+ coverageProvider: 'v8',
12
+ coverageReporters: ['text-summary'],
13
+ }
14
+
15
+ export default config
package/package.json ADDED
@@ -0,0 +1,67 @@
1
+ {
2
+ "name": "@midseelee/date-fns-buddhist-adapter",
3
+ "repository": "https://github.com/midseelee/date-fns-buddhist-adapter.git",
4
+ "version": "1.0.0",
5
+ "description": "date-fns adapter with Buddhist years functionality",
6
+ "main": "dist/index.js",
7
+ "types": "dist/index.d.ts",
8
+ "private": false,
9
+ "scripts": {
10
+ "test": "jest",
11
+ "test:watch": "jest --watch",
12
+ "test:coverage": "jest --coverage",
13
+ "build": "tsc",
14
+ "build:watch": "tsc --watch",
15
+ "dev": "tsc --watch",
16
+ "prepare": "husky install",
17
+ "prepublishOnly": "bun run typecheck && bun run test && bun run build",
18
+ "lint": "prettier --check \"**/*.{md,yml,json}\" && eslint .",
19
+ "lint:fix": "prettier --write \"**/*.{md,yml,json}\" && eslint . --fix",
20
+ "typecheck": "tsc --noEmit",
21
+ "clean": "rm -rf dist",
22
+ "rebuild": "bun run clean && bun run build",
23
+ "example:dev": "cd example && pnpm dev",
24
+ "start": "bun src/index.ts"
25
+ },
26
+ "keywords": [
27
+ "date",
28
+ "date-fns",
29
+ "date-io",
30
+ "buddhist",
31
+ "date-picker",
32
+ "mui-x",
33
+ "react"
34
+ ],
35
+ "author": "midseelee",
36
+ "license": "MIT",
37
+ "engines": {
38
+ "node": ">=8.16.0",
39
+ "pnpm": ">=8.6.0"
40
+ },
41
+ "dependencies": {
42
+ "@date-io/date-fns": "3.2.1",
43
+ "@mui/material": "7.3.4",
44
+ "date-fns": "4.1.0",
45
+ "react": "19.2.0"
46
+ },
47
+ "devDependencies": {
48
+ "@tsconfig/node-lts": "22.0.2",
49
+ "@types/jest": "30.0.0",
50
+ "@types/node": "24.8.1",
51
+ "@types/react": "19.2.2",
52
+ "@typescript-eslint/eslint-plugin": "8.46.1",
53
+ "@typescript-eslint/parser": "8.46.1",
54
+ "eslint": "9.37.0",
55
+ "eslint-config-prettier": "10.1.8",
56
+ "eslint-import-resolver-typescript": "4.4.4",
57
+ "eslint-plugin-import": "2.32.0",
58
+ "eslint-plugin-jest": "29.0.1",
59
+ "eslint-plugin-prettier": "5.5.4",
60
+ "husky": "9.1.7",
61
+ "jest": "30.2.0",
62
+ "prettier": "3.6.2",
63
+ "ts-jest": "29.4.5",
64
+ "ts-node": "10.9.2",
65
+ "typescript": "5.9.3"
66
+ }
67
+ }