persian-date-kit 0.0.10 → 0.0.12

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.
Files changed (2) hide show
  1. package/README.md +86 -53
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -6,6 +6,10 @@ Production-ready Persian (Jalali) date pickers for React.
6
6
 
7
7
  **Repository:** [https://github.com/aliseyedabady/darvix-persian-date-kit](https://github.com/aliseyedabady/darvix-persian-date-kit)
8
8
 
9
+ ## Demo
10
+
11
+ ![persian-date-kit demo](public/demo.webp)
12
+
9
13
  ## Key principles
10
14
  - **Gregorian-only internally**: component values are always `Date | null` (Gregorian). Jalali is only for display/input.
11
15
  - **Controlled components**: you own the state (`value` + `onChange`).
@@ -135,64 +139,82 @@ All values you receive in `onChange` are **Gregorian** (`Date | null`). Jalali i
135
139
 
136
140
  ### `PersianDatePicker`
137
141
 
138
- #### Required props
139
- - **`value`**: `Date | null` — controlled value (Gregorian)
140
- - **`onChange`**: `(date: Date | null) => void` controlled change handler
141
-
142
- #### Extra props (single picker)
143
- - **`placeholder?`**: `string` input placeholder (popover mode)
144
- - **`classes?`**: `PersianDatePickerClasses` — per-slot class overrides
142
+ | Prop | Type | Default | Description |
143
+ |---|---|---:|---|
144
+ | `value` | `Date \| null` || Controlled value (**Gregorian**) |
145
+ | `onChange` | `(date: Date \| null) => void` | — | Called with the next value (**Gregorian**) |
146
+ | `placeholder?` | `string` | `undefined` | Input placeholder (popover mode) |
147
+ | `classes?` | `PersianDatePickerClasses` | `undefined` | Per-slot class overrides (see **Classes table** below) |
145
148
 
146
149
  ### `PersianDateRangePicker`
147
150
 
148
- #### Required props
149
- - **`value`**: `{ start: Date | null; end: Date | null }` — controlled range (Gregorian)
150
- - **`onChange`**: `(range: { start: Date | null; end: Date | null }) => void`
151
-
152
- #### Extra props (range picker)
153
- - **`inputVariant?`**: `'two' | 'single'` two inputs (default) or one combined input
154
- - **`placeholder?`**: `string` used for single-input mode
155
- - **`rangeSeparator?`**: `string` separator for single-input text (default: `" - "`)
156
- - **`placeholderStart?` / `placeholderEnd?`**: `string` used for two-input mode
157
- - **`classes?`**: `PersianDateRangePickerClasses` per-slot class overrides
151
+ | Prop | Type | Default | Description |
152
+ |---|---|---:|---|
153
+ | `value` | `{ start: Date \| null; end: Date \| null }` | — | Controlled range (**Gregorian**) |
154
+ | `onChange` | `(range: { start: Date \| null; end: Date \| null }) => void` | — | Called with the next range (**Gregorian**) |
155
+ | `inputVariant?` | `'two' \| 'single'` | `'two'` | Two inputs (start/end) or a single combined input |
156
+ | `placeholder?` | `string` | `undefined` | Placeholder for **single** input mode |
157
+ | `rangeSeparator?` | `string` | `" - "` | Separator used in single-input mode (`start{sep}end`) |
158
+ | `placeholderStart?` | `string` | `undefined` | Placeholder for start input (two-input mode) |
159
+ | `placeholderEnd?` | `string` | `undefined` | Placeholder for end input (two-input mode) |
160
+ | `classes?` | `PersianDateRangePickerClasses` | `undefined` | Per-slot class overrides (see **Classes table** below) |
158
161
 
159
162
  ### Shared props (`BasePickerProps`)
160
163
 
161
164
  These props exist on both pickers:
162
165
 
163
- - **`minDate?` / `maxDate?`**: `Date` limits selectable days (Gregorian)
164
- - **`disabled?`**: `boolean`
165
- - **`mode?`**: `'popover' | 'inline'` default is `'popover'`
166
- - **`open?` / `onOpenChange?`**: control popover open state (only meaningful in popover mode)
167
- - **`popover?`**: `PopoverConfig` positioning options (popover mode)
168
- - **`formatValue?`**: `(date: Date) => string` formats input text (default: numeric Jalali `YYYY/MM/DD`)
169
- - **`parseValue?`**: `(text: string) => Date | null` parses input text into Gregorian (default: numeric Jalali `YYYY/MM/DD`)
170
- - **`weekdays?`**: `string[]` 7 labels for weekday header (if omitted, the picker uses numeric labels)
171
- - **`monthLabels?`**: `string[]` 12 labels (index 0 => month 1). If omitted, month numbers are shown.
172
- - **`renderMonthLabel?`**: `(jy: number, jm: number) => React.ReactNode` custom header label
173
- - **`prevIcon?` / `nextIcon?`**: `React.ReactNode` customize navigation icons
174
- - **`className?`**: `string` extra class on root
166
+ | Prop | Type | Default | Description |
167
+ |---|---|---:|---|
168
+ | `minDate?` | `Date` | `undefined` | Minimum selectable day (**Gregorian**) |
169
+ | `maxDate?` | `Date` | `undefined` | Maximum selectable day (**Gregorian**) |
170
+ | `disabled?` | `boolean` | `false` | Disable interactions |
171
+ | `mode?` | `'popover' \| 'inline'` | `'popover'` | `inline` shows calendar without input |
172
+ | `open?` | `boolean` | `undefined` | Control popover open state (popover mode) |
173
+ | `onOpenChange?` | `(open: boolean) => void` | `undefined` | Notified when open state changes (popover mode) |
174
+ | `popover?` | `PopoverConfig` | `{ portal: true }` | Popover positioning options (popover mode) |
175
+ | `formatValue?` | `(date: Date) => string` | built-in | Format input display (default: numeric Jalali `YYYY/MM/DD`) |
176
+ | `parseValue?` | `(text: string) => Date \| null` | built-in | Parse user text into **Gregorian** (default: numeric Jalali `YYYY/MM/DD`) |
177
+ | `weekdays?` | `string[]` | numeric | 7 weekday labels; if omitted, numeric labels are shown |
178
+ | `monthLabels?` | `string[]` | numeric | 12 month labels (index 0 => month 1); if omitted, month numbers |
179
+ | `renderMonthLabel?` | `(jy: number, jm: number) => React.ReactNode` | `undefined` | Custom header label renderer |
180
+ | `prevIcon?` | `React.ReactNode` | `undefined` | Custom previous icon |
181
+ | `nextIcon?` | `React.ReactNode` | `undefined` | Custom next icon |
182
+ | `className?` | `string` | `undefined` | Extra class on the root element |
175
183
 
176
184
  ### `PopoverConfig`
177
185
 
178
- - **`portal?`**: `boolean` (default: `true`) recommended inside modals / overflow containers
179
- - **`gutter?`**: `number` (default: `8`) — gap between anchor and popover
180
- - **`padding?`**: `number` (default: `8`) minimum distance from viewport edges (clamping)
181
- - **`strategy?`**: `'fixed' | 'absolute'` (default: `'fixed'`)
182
- - **`placements?`**: `Array<'bottom' | 'top' | 'left' | 'right'>` (default: `['bottom','top','left','right']`)
183
- - **`align?`**: `'start' | 'center' | 'end'` (default: `'end'`)
186
+ | Prop | Type | Default | Description |
187
+ |---|---|---:|---|
188
+ | `portal?` | `boolean` | `true` | Render popover in a portal (recommended for **modals/overflow** containers) |
189
+ | `gutter?` | `number` | `8` | Gap between anchor and popover |
190
+ | `padding?` | `number` | `8` | Minimum distance from viewport edges (clamping) |
191
+ | `strategy?` | `'fixed' \| 'absolute'` | `'fixed'` | Positioning strategy |
192
+ | `placements?` | `Array<'bottom' \| 'top' \| 'left' \| 'right'>` | `['bottom','top','left','right']` | Preferred placements order (auto-flip chooses best fit) |
193
+ | `align?` | `'start' \| 'center' \| 'end'` | `'end'` | Cross-axis alignment |
184
194
 
185
195
  ### Styling slots (`classes`)
186
196
 
187
- You can override the class names per slot:
188
-
189
- - **Base slots** (`BasePickerClasses`):
190
- - `root`, `input`, `button`, `popover`, `header`, `navButton`, `monthLabel`, `grid`, `weekday`
191
- - `day`, `dayOutside`, `dayDisabled`, `dayToday`
192
- - **Single picker extra slots** (`PersianDatePickerClasses`):
193
- - `daySelected`
194
- - **Range picker extra slots** (`PersianDateRangePickerClasses`):
195
- - `dayRangeStart`, `dayRangeEnd`, `dayInRange`
197
+ You can override class names per slot:
198
+
199
+ | Slot | Used for |
200
+ |---|---|
201
+ | `root` | Root wrapper |
202
+ | `input` | Input element |
203
+ | `button` | Clear button (single picker) |
204
+ | `popover` | Popover container |
205
+ | `header` | Calendar header |
206
+ | `navButton` | Navigation buttons (prev/next) |
207
+ | `monthLabel` | Header month/year label button |
208
+ | `grid` | Grid container |
209
+ | `weekday` | Weekday header cell |
210
+ | `day` | Day button |
211
+ | `dayOutside` | Day that belongs to adjacent month |
212
+ | `dayDisabled` | Disabled day |
213
+ | `dayToday` | Today day |
214
+ | `daySelected` | **Single picker** selected day |
215
+ | `dayInRange` | **Range picker** day inside range |
216
+ | `dayRangeStart` | **Range picker** range start day |
217
+ | `dayRangeEnd` | **Range picker** range end day |
196
218
 
197
219
  ## Styling / Theming
198
220
 
@@ -208,15 +230,17 @@ The default CSS is built around **CSS variables**, so it’s easy to theme.
208
230
 
209
231
  These variables control most of the look:
210
232
 
211
- - `--dvx-pdp-bg`
212
- - `--dvx-pdp-fg`
213
- - `--dvx-pdp-muted`
214
- - `--dvx-pdp-border`
215
- - `--dvx-pdp-shadow`
216
- - `--dvx-pdp-accent`
217
- - `--dvx-pdp-accentFg`
218
- - `--dvx-pdp-ring`
219
- - `--dvx-pdp-dayHover`
233
+ | CSS variable | Purpose | Default (light) |
234
+ |---|---|---|
235
+ | `--dvx-pdp-bg` | Surface background | `#ffffff` |
236
+ | `--dvx-pdp-fg` | Main text | `#111827` |
237
+ | `--dvx-pdp-muted` | Muted text | `#6b7280` |
238
+ | `--dvx-pdp-border` | Borders | `#e5e7eb` |
239
+ | `--dvx-pdp-shadow` | Popover shadow | `0 10px 20px rgba(0, 0, 0, 0.08)` |
240
+ | `--dvx-pdp-accent` | Accent / selected | `#2563eb` |
241
+ | `--dvx-pdp-accentFg` | Text on accent | `#ffffff` |
242
+ | `--dvx-pdp-ring` | Focus ring | `rgba(37, 99, 235, 0.3)` |
243
+ | `--dvx-pdp-dayHover` | Hover background | `rgba(37, 99, 235, 0.08)` |
220
244
 
221
245
  Example:
222
246
 
@@ -249,6 +273,15 @@ If you **don’t** import `styles.css`, you should provide your own CSS for the
249
273
  component class hooks (ex: `.dvx-pdp`, `.dvx-pdp__input`, `.dvx-pdp__day`, ...),
250
274
  or rely entirely on `classes` and your own styles.
251
275
 
276
+ ### Styling approaches (summary table)
277
+
278
+ | Approach | What you do | Best for |
279
+ |---|---|---|
280
+ | Default styles | Import `persian-date-kit/styles.css` | Fastest start, good baseline |
281
+ | Theme variables | Override `--dvx-pdp-*` in your CSS | Brand theming without rewriting CSS |
282
+ | `classes` overrides | Pass Tailwind/utility classes via `classes` | Integrate into your design system |
283
+ | Full custom | Don’t import `styles.css`; write your own | Complete visual control |
284
+
252
285
  ## Development (this repo)
253
286
 
254
287
  Clone the repository:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "persian-date-kit",
3
- "version": "0.0.10",
3
+ "version": "0.0.12",
4
4
  "description": "Production-ready Persian (Jalali) date pickers for React with Gregorian-only values.",
5
5
  "keywords": [
6
6
  "react",