feat: working
continuous-integration/drone/push Build is failing Details

master
Guillermo Pages 4 months ago
parent 8611d080ae
commit 48b5002f2f

@ -2,12 +2,12 @@
A modern, flexible, and highly customizable calendar component library for React with TypeScript support. A modern, flexible, and highly customizable calendar component library for React with TypeScript support.
## 🆕 Version 1.3.0 Features ## 🆕 Version 1.4.0 Features
- 📅 **Today State in Color Schemes**: Define custom colors for today's date through color schemes - 📅 **Today in Any State**: Define custom colors for today's date in any state (default, active, rangeStart, etc.)
- ✏️ **Header Text Transform**: Custom function to transform day name display (e.g., `dayName => dayName.slice(0, 2)`) - ✏️ **Header Text Transform**: Custom function to transform day name display (e.g., `dayName => dayName.slice(0, 2)`)
- 🌍 **International Locale Support**: Full internationalization with 50+ languages via date-fns - 🌍 **International Locale Support**: Full internationalization with 50+ languages via date-fns
- 🎨 **Comprehensive Color Schemes**: Complete control over colors for every state (default, today, selecting, selected, range start/end/mid, active) and day type (weekday/weekend) - 🎨 **Three-Dimensional Color Schemes**: Control colors by week split (weekday/weekend), relative (today/anyday), and state
- 🎯 **Enhanced Weekend Support**: Distinct colors for weekends in all selection states - 🎯 **Enhanced Weekend Support**: Distinct colors for weekends in all selection states
📖 **[View the complete Usage Guide](./USAGE_GUIDE.md)** for detailed examples of the new features! 📖 **[View the complete Usage Guide](./USAGE_GUIDE.md)** for detailed examples of the new features!

@ -71,26 +71,37 @@ Full control over colors for every state and day type:
import { Year, ColorScheme } from 'react-calendario'; import { Year, ColorScheme } from 'react-calendario';
const colorScheme: ColorScheme = [ const colorScheme: ColorScheme = [
// Today's date colors (highest priority) // Today's date colors for different states
{ {
type: 'weekday', weekSplit: 'weekday',
state: 'today', // Today if it's a weekday relative: 'today',
state: 'default', // Today when it's a normal weekday
colors: { colors: {
header: { backgroundColor: '#ffd700', color: '#000000' }, header: { backgroundColor: '#ffd700', color: '#000000' },
content: { backgroundColor: '#fff9e6', color: '#000000' } content: { backgroundColor: '#fff9e6', color: '#000000' }
} }
}, },
{ {
type: 'weekend', weekSplit: 'weekday',
state: 'today', // Today if it's a weekend relative: 'today',
state: 'active', // Today when it's active/clicked
colors: { colors: {
header: { backgroundColor: '#ffb347', color: '#000000' }, header: { backgroundColor: '#ffed4e', color: '#000000' },
content: { backgroundColor: '#fff5e6', color: '#000000' } content: { backgroundColor: '#fff59d', color: '#000000' }
} }
}, },
// Weekday colors
{ {
type: 'weekday', weekSplit: 'weekday',
relative: 'today',
state: 'rangeStart', // Today when it starts a range
colors: {
header: { backgroundColor: '#ffc107', color: '#000000' },
content: { backgroundColor: '#ffeb3b', color: '#000000' }
}
},
// Regular weekday colors (anyday is default when relative is omitted)
{
weekSplit: 'weekday',
state: 'default', // Normal weekday state: 'default', // Normal weekday
colors: { colors: {
header: { backgroundColor: '#2c3e50', color: '#ffffff' }, header: { backgroundColor: '#2c3e50', color: '#ffffff' },
@ -98,7 +109,7 @@ const colorScheme: ColorScheme = [
} }
}, },
{ {
type: 'weekday', weekSplit: 'weekday',
state: 'rangeStart', // First day of selected range state: 'rangeStart', // First day of selected range
colors: { colors: {
header: { backgroundColor: '#2980b9', color: '#ffffff' }, header: { backgroundColor: '#2980b9', color: '#ffffff' },
@ -106,7 +117,7 @@ const colorScheme: ColorScheme = [
} }
}, },
{ {
type: 'weekday', weekSplit: 'weekday',
state: 'rangeMid', // Middle days of selected range state: 'rangeMid', // Middle days of selected range
colors: { colors: {
header: { backgroundColor: '#5dade2', color: '#ffffff' }, header: { backgroundColor: '#5dade2', color: '#ffffff' },
@ -116,7 +127,7 @@ const colorScheme: ColorScheme = [
// Weekend colors // Weekend colors
{ {
type: 'weekend', weekSplit: 'weekend',
state: 'default', // Normal weekend state: 'default', // Normal weekend
colors: { colors: {
header: { backgroundColor: '#7f8c8d', color: '#ffffff' }, header: { backgroundColor: '#7f8c8d', color: '#ffffff' },
@ -124,7 +135,7 @@ const colorScheme: ColorScheme = [
} }
}, },
{ {
type: 'weekend', weekSplit: 'weekend',
state: 'rangeStart', // Weekend that starts a range state: 'rangeStart', // Weekend that starts a range
colors: { colors: {
header: { backgroundColor: '#2980b9', color: '#ffffff' }, header: { backgroundColor: '#2980b9', color: '#ffffff' },
@ -140,19 +151,26 @@ const colorScheme: ColorScheme = [
/> />
``` ```
#### Available States: #### Color Scheme Dimensions:
**Week Split** (`weekSplit`):
- `weekday` - Monday through Friday
- `weekend` - Saturday and Sunday (or custom weekend days)
**Relative** (`relative`, optional):
- `today` - Today's date (automatically detected)
- `anyday` - Any other date (default when omitted)
**State** (`state`):
- `default` - Normal day appearance - `default` - Normal day appearance
- `today` - Today's date (automatically detected, highest priority) - `selecting` - Day is being hovered during selection
- `selected` - Day is part of a completed selection (deprecated, use `rangeMid`)
- `selecting` - Day is being hovered during selection (important for weekends!)
- `rangeStart` - First day of a range - `rangeStart` - First day of a range
- `rangeEnd` - Last day of a range - `rangeEnd` - Last day of a range
- `rangeMid` - Middle days of a selected range - `rangeMid` - Middle days of a selected range
- `active` - Special highlighted days (holidays, events) - `active` - Special highlighted days (holidays, events)
#### Day Types: #### Backwards Compatibility:
- `weekday` - Monday through Friday - `type` is still supported but deprecated (use `weekSplit` instead)
- `weekend` - Saturday and Sunday (or custom weekend days)
## 🌍 Locale Support ## 🌍 Locale Support

@ -1,6 +1,6 @@
{ {
"name": "react-calendario", "name": "react-calendario",
"version": "1.3.1", "version": "1.4.1",
"description": "A modern, flexible calendar component for React with TypeScript support", "description": "A modern, flexible calendar component for React with TypeScript support",
"type": "module", "type": "module",
"main": "dist/index.umd.js", "main": "dist/index.umd.js",

@ -190,11 +190,6 @@
} }
// end implicit (midrange) { // end implicit (midrange) {
// today state - no default styling, handled by color scheme
&.Day__Container--today {
// Today state can combine with other states
// Styling is handled through the color scheme
}
// active state - inverted colors // active state - inverted colors
&.Day__Container--active { &.Day__Container--active {

@ -46,7 +46,6 @@ export const Day: React.FC<DayProps> = ({
[styles['Day__Container--rowStart']]: variations.includes('rowStart'), [styles['Day__Container--rowStart']]: variations.includes('rowStart'),
[styles['Day__Container--rowEnd']]: variations.includes('rowEnd'), [styles['Day__Container--rowEnd']]: variations.includes('rowEnd'),
[styles['Day__Container--active']]: variations.includes('active'), [styles['Day__Container--active']]: variations.includes('active'),
[styles['Day__Container--today']]: variations.includes('today'),
[styles['magnify']]: magnify && (variations.includes('selected') || variations.includes('selecting')) [styles['magnify']]: magnify && (variations.includes('selected') || variations.includes('selecting'))
}, },
styles[`Day--${headerStyle}`], styles[`Day--${headerStyle}`],

@ -39,184 +39,200 @@ export const InteractiveDateRange: React.FC = () => {
// Color schemes with proper weekend and today support // Color schemes with proper weekend and today support
const colorSchemes: Record<string, ColorScheme> = { const colorSchemes: Record<string, ColorScheme> = {
ocean: [ ocean: [
// Today state (highest priority) // Today's date colors (any state)
{ type: 'weekday', state: 'today', colors: { { weekSplit: 'weekday', relative: 'today', state: 'default', colors: {
header: { backgroundColor: '#ffd700', color: '#000000' }, header: { backgroundColor: '#ffd700', color: '#000000' },
content: { backgroundColor: '#fff9e6', color: '#000000' } content: { backgroundColor: '#fff9e6', color: '#000000' }
}}, }},
{ type: 'weekend', state: 'today', colors: { { weekSplit: 'weekend', relative: 'today', state: 'default', colors: {
header: { backgroundColor: '#ffb347', color: '#000000' }, header: { backgroundColor: '#ffb347', color: '#000000' },
content: { backgroundColor: '#fff5e6', color: '#000000' } content: { backgroundColor: '#fff5e6', color: '#000000' }
}}, }},
// Weekday states { weekSplit: 'weekday', relative: 'today', state: 'active', colors: {
{ type: 'weekday', state: 'default', colors: { header: { backgroundColor: '#ffed4e', color: '#000000' },
content: { backgroundColor: '#fff59d', color: '#000000' }
}},
{ weekSplit: 'weekday', relative: 'today', state: 'rangeStart', colors: {
header: { backgroundColor: '#ffc107', color: '#000000' },
content: { backgroundColor: '#ffeb3b', color: '#000000' }
}},
// Weekday states (anyday - default when relative is omitted)
{ weekSplit: 'weekday', state: 'default', colors: {
header: { backgroundColor: '#006994', color: '#ffffff' }, header: { backgroundColor: '#006994', color: '#ffffff' },
content: { backgroundColor: '#ffffff', color: '#006994' } content: { backgroundColor: '#ffffff', color: '#006994' }
}}, }},
{ type: 'weekday', state: 'selecting', colors: { { weekSplit: 'weekday', state: 'selecting', colors: {
header: { backgroundColor: '#4a90a4', color: '#ffffff' }, header: { backgroundColor: '#4a90a4', color: '#ffffff' },
content: { backgroundColor: '#e8f4f8', color: '#006994' } content: { backgroundColor: '#e8f4f8', color: '#006994' }
}}, }},
{ type: 'weekday', state: 'rangeStart', colors: { { weekSplit: 'weekday', state: 'rangeStart', colors: {
header: { backgroundColor: '#004d6f', color: '#ffffff' }, header: { backgroundColor: '#004d6f', color: '#ffffff' },
content: { backgroundColor: '#0084b4', color: '#ffffff' } content: { backgroundColor: '#0084b4', color: '#ffffff' }
}}, }},
{ type: 'weekday', state: 'rangeEnd', colors: { { weekSplit: 'weekday', state: 'rangeEnd', colors: {
header: { backgroundColor: '#004d6f', color: '#ffffff' }, header: { backgroundColor: '#004d6f', color: '#ffffff' },
content: { backgroundColor: '#0084b4', color: '#ffffff' } content: { backgroundColor: '#0084b4', color: '#ffffff' }
}}, }},
{ type: 'weekday', state: 'rangeMid', colors: { { weekSplit: 'weekday', state: 'rangeMid', colors: {
header: { backgroundColor: '#3ca0c8', color: '#ffffff' }, header: { backgroundColor: '#3ca0c8', color: '#ffffff' },
content: { backgroundColor: '#b3d9ea', color: '#004d6f' } content: { backgroundColor: '#b3d9ea', color: '#004d6f' }
}}, }},
{ type: 'weekday', state: 'active', colors: { { weekSplit: 'weekday', state: 'active', colors: {
header: { backgroundColor: '#00a8e8', color: '#ffffff' }, header: { backgroundColor: '#00a8e8', color: '#ffffff' },
content: { backgroundColor: '#007ea7', color: '#ffffff' } content: { backgroundColor: '#007ea7', color: '#ffffff' }
}}, }},
// Weekend states - with subtle differentiation // Weekend states - with subtle differentiation
{ type: 'weekend', state: 'default', colors: { { weekSplit: 'weekend', state: 'default', colors: {
header: { backgroundColor: '#5c8ca3', color: '#ffffff' }, header: { backgroundColor: '#5c8ca3', color: '#ffffff' },
content: { backgroundColor: '#f0f6f9', color: '#3d5a6c' } content: { backgroundColor: '#f0f6f9', color: '#3d5a6c' }
}}, }},
{ type: 'weekend', state: 'selecting', colors: { { weekSplit: 'weekend', state: 'selecting', colors: {
header: { backgroundColor: '#7aa3b8', color: '#ffffff' }, header: { backgroundColor: '#7aa3b8', color: '#ffffff' },
content: { backgroundColor: '#dde9f0', color: '#4a6b7c' } content: { backgroundColor: '#dde9f0', color: '#4a6b7c' }
}}, }},
{ type: 'weekend', state: 'rangeStart', colors: { { weekSplit: 'weekend', state: 'rangeStart', colors: {
header: { backgroundColor: '#003f5c', color: '#ffffff' }, header: { backgroundColor: '#003f5c', color: '#ffffff' },
content: { backgroundColor: '#006d94', color: '#ffffff' } content: { backgroundColor: '#006d94', color: '#ffffff' }
}}, }},
{ type: 'weekend', state: 'rangeEnd', colors: { { weekSplit: 'weekend', state: 'rangeEnd', colors: {
header: { backgroundColor: '#003f5c', color: '#ffffff' }, header: { backgroundColor: '#003f5c', color: '#ffffff' },
content: { backgroundColor: '#006d94', color: '#ffffff' } content: { backgroundColor: '#006d94', color: '#ffffff' }
}}, }},
{ type: 'weekend', state: 'rangeMid', colors: { { weekSplit: 'weekend', state: 'rangeMid', colors: {
header: { backgroundColor: '#6eb5d0', color: '#ffffff' }, header: { backgroundColor: '#6eb5d0', color: '#ffffff' },
content: { backgroundColor: '#cce5f0', color: '#003f5c' } content: { backgroundColor: '#cce5f0', color: '#003f5c' }
}}, }},
{ type: 'weekend', state: 'active', colors: { { weekSplit: 'weekend', state: 'active', colors: {
header: { backgroundColor: '#0096c7', color: '#ffffff' }, header: { backgroundColor: '#0096c7', color: '#ffffff' },
content: { backgroundColor: '#0077b6', color: '#ffffff' } content: { backgroundColor: '#0077b6', color: '#ffffff' }
}} }}
], ],
sunset: [ sunset: [
// Today state // Today's date colors
{ type: 'weekday', state: 'today', colors: { { weekSplit: 'weekday', relative: 'today', state: 'default', colors: {
header: { backgroundColor: '#ff1744', color: '#ffffff' }, header: { backgroundColor: '#ff1744', color: '#ffffff' },
content: { backgroundColor: '#ffebee', color: '#c62828' } content: { backgroundColor: '#ffebee', color: '#c62828' }
}}, }},
{ type: 'weekend', state: 'today', colors: { { weekSplit: 'weekend', relative: 'today', state: 'default', colors: {
header: { backgroundColor: '#ff6b6b', color: '#ffffff' }, header: { backgroundColor: '#ff6b6b', color: '#ffffff' },
content: { backgroundColor: '#ffe0e0', color: '#d32f2f' } content: { backgroundColor: '#ffe0e0', color: '#d32f2f' }
}}, }},
{ weekSplit: 'weekday', relative: 'today', state: 'active', colors: {
header: { backgroundColor: '#ff5252', color: '#ffffff' },
content: { backgroundColor: '#ffcdd2', color: '#b71c1c' }
}},
// Weekday states // Weekday states
{ type: 'weekday', state: 'default', colors: { { weekSplit: 'weekday', state: 'default', colors: {
header: { backgroundColor: '#ff6b35', color: '#ffffff' }, header: { backgroundColor: '#ff6b35', color: '#ffffff' },
content: { backgroundColor: '#ffffff', color: '#ff6b35' } content: { backgroundColor: '#ffffff', color: '#ff6b35' }
}}, }},
{ type: 'weekday', state: 'selecting', colors: { { weekSplit: 'weekday', state: 'selecting', colors: {
header: { backgroundColor: '#ff8c5a', color: '#ffffff' }, header: { backgroundColor: '#ff8c5a', color: '#ffffff' },
content: { backgroundColor: '#ffe8df', color: '#c94820' } content: { backgroundColor: '#ffe8df', color: '#c94820' }
}}, }},
{ type: 'weekday', state: 'rangeStart', colors: { { weekSplit: 'weekday', state: 'rangeStart', colors: {
header: { backgroundColor: '#d84315', color: '#ffffff' }, header: { backgroundColor: '#d84315', color: '#ffffff' },
content: { backgroundColor: '#ff5722', color: '#ffffff' } content: { backgroundColor: '#ff5722', color: '#ffffff' }
}}, }},
{ type: 'weekday', state: 'rangeEnd', colors: { { weekSplit: 'weekday', state: 'rangeEnd', colors: {
header: { backgroundColor: '#d84315', color: '#ffffff' }, header: { backgroundColor: '#d84315', color: '#ffffff' },
content: { backgroundColor: '#ff5722', color: '#ffffff' } content: { backgroundColor: '#ff5722', color: '#ffffff' }
}}, }},
{ type: 'weekday', state: 'rangeMid', colors: { { weekSplit: 'weekday', state: 'rangeMid', colors: {
header: { backgroundColor: '#ff8a65', color: '#ffffff' }, header: { backgroundColor: '#ff8a65', color: '#ffffff' },
content: { backgroundColor: '#ffccbc', color: '#bf360c' } content: { backgroundColor: '#ffccbc', color: '#bf360c' }
}}, }},
{ type: 'weekday', state: 'active', colors: { { weekSplit: 'weekday', state: 'active', colors: {
header: { backgroundColor: '#f4511e', color: '#ffffff' }, header: { backgroundColor: '#f4511e', color: '#ffffff' },
content: { backgroundColor: '#e64a19', color: '#ffffff' } content: { backgroundColor: '#e64a19', color: '#ffffff' }
}}, }},
// Weekend states // Weekend states
{ type: 'weekend', state: 'default', colors: { { weekSplit: 'weekend', state: 'default', colors: {
header: { backgroundColor: '#ff9671', color: '#ffffff' }, header: { backgroundColor: '#ff9671', color: '#ffffff' },
content: { backgroundColor: '#fff4f0', color: '#cc5030' } content: { backgroundColor: '#fff4f0', color: '#cc5030' }
}}, }},
{ type: 'weekend', state: 'selecting', colors: { { weekSplit: 'weekend', state: 'selecting', colors: {
header: { backgroundColor: '#ffab8f', color: '#ffffff' }, header: { backgroundColor: '#ffab8f', color: '#ffffff' },
content: { backgroundColor: '#ffe0d6', color: '#b84020' } content: { backgroundColor: '#ffe0d6', color: '#b84020' }
}}, }},
{ type: 'weekend', state: 'rangeStart', colors: { { weekSplit: 'weekend', state: 'rangeStart', colors: {
header: { backgroundColor: '#bf360c', color: '#ffffff' }, header: { backgroundColor: '#bf360c', color: '#ffffff' },
content: { backgroundColor: '#ff6e40', color: '#ffffff' } content: { backgroundColor: '#ff6e40', color: '#ffffff' }
}}, }},
{ type: 'weekend', state: 'rangeEnd', colors: { { weekSplit: 'weekend', state: 'rangeEnd', colors: {
header: { backgroundColor: '#bf360c', color: '#ffffff' }, header: { backgroundColor: '#bf360c', color: '#ffffff' },
content: { backgroundColor: '#ff6e40', color: '#ffffff' } content: { backgroundColor: '#ff6e40', color: '#ffffff' }
}}, }},
{ type: 'weekend', state: 'rangeMid', colors: { { weekSplit: 'weekend', state: 'rangeMid', colors: {
header: { backgroundColor: '#ffab91', color: '#ffffff' }, header: { backgroundColor: '#ffab91', color: '#ffffff' },
content: { backgroundColor: '#ffddd2', color: '#a73010' } content: { backgroundColor: '#ffddd2', color: '#a73010' }
}}, }},
{ type: 'weekend', state: 'active', colors: { { weekSplit: 'weekend', state: 'active', colors: {
header: { backgroundColor: '#ff3d00', color: '#ffffff' }, header: { backgroundColor: '#ff3d00', color: '#ffffff' },
content: { backgroundColor: '#ff6e40', color: '#ffffff' } content: { backgroundColor: '#ff6e40', color: '#ffffff' }
}} }}
], ],
forest: [ forest: [
// Today state // Today's date colors
{ type: 'weekday', state: 'today', colors: { { weekSplit: 'weekday', relative: 'today', state: 'default', colors: {
header: { backgroundColor: '#66bb6a', color: '#ffffff' }, header: { backgroundColor: '#66bb6a', color: '#ffffff' },
content: { backgroundColor: '#e8f5e9', color: '#2e7d32' } content: { backgroundColor: '#e8f5e9', color: '#2e7d32' }
}}, }},
{ type: 'weekend', state: 'today', colors: { { weekSplit: 'weekend', relative: 'today', state: 'default', colors: {
header: { backgroundColor: '#81c784', color: '#ffffff' }, header: { backgroundColor: '#81c784', color: '#ffffff' },
content: { backgroundColor: '#f1f8e9', color: '#33691e' } content: { backgroundColor: '#f1f8e9', color: '#33691e' }
}}, }},
{ weekSplit: 'weekday', relative: 'today', state: 'rangeStart', colors: {
header: { backgroundColor: '#4caf50', color: '#ffffff' },
content: { backgroundColor: '#c8e6c9', color: '#1b5e20' }
}},
// Weekday states // Weekday states
{ type: 'weekday', state: 'default', colors: { { weekSplit: 'weekday', state: 'default', colors: {
header: { backgroundColor: '#2d6a4f', color: '#ffffff' }, header: { backgroundColor: '#2d6a4f', color: '#ffffff' },
content: { backgroundColor: '#ffffff', color: '#2d6a4f' } content: { backgroundColor: '#ffffff', color: '#2d6a4f' }
}}, }},
{ type: 'weekday', state: 'selecting', colors: { { weekSplit: 'weekday', state: 'selecting', colors: {
header: { backgroundColor: '#52b788', color: '#ffffff' }, header: { backgroundColor: '#52b788', color: '#ffffff' },
content: { backgroundColor: '#d8f3dc', color: '#1b5e3f' } content: { backgroundColor: '#d8f3dc', color: '#1b5e3f' }
}}, }},
{ type: 'weekday', state: 'rangeStart', colors: { { weekSplit: 'weekday', state: 'rangeStart', colors: {
header: { backgroundColor: '#1b5e3f', color: '#ffffff' }, header: { backgroundColor: '#1b5e3f', color: '#ffffff' },
content: { backgroundColor: '#40916c', color: '#ffffff' } content: { backgroundColor: '#40916c', color: '#ffffff' }
}}, }},
{ type: 'weekday', state: 'rangeEnd', colors: { { weekSplit: 'weekday', state: 'rangeEnd', colors: {
header: { backgroundColor: '#1b5e3f', color: '#ffffff' }, header: { backgroundColor: '#1b5e3f', color: '#ffffff' },
content: { backgroundColor: '#40916c', color: '#ffffff' } content: { backgroundColor: '#40916c', color: '#ffffff' }
}}, }},
{ type: 'weekday', state: 'rangeMid', colors: { { weekSplit: 'weekday', state: 'rangeMid', colors: {
header: { backgroundColor: '#74c69d', color: '#ffffff' }, header: { backgroundColor: '#74c69d', color: '#ffffff' },
content: { backgroundColor: '#b7e4c7', color: '#1b5e3f' } content: { backgroundColor: '#b7e4c7', color: '#1b5e3f' }
}}, }},
{ type: 'weekday', state: 'active', colors: { { weekSplit: 'weekday', state: 'active', colors: {
header: { backgroundColor: '#388e3c', color: '#ffffff' }, header: { backgroundColor: '#388e3c', color: '#ffffff' },
content: { backgroundColor: '#2e7d32', color: '#ffffff' } content: { backgroundColor: '#2e7d32', color: '#ffffff' }
}}, }},
// Weekend states // Weekend states
{ type: 'weekend', state: 'default', colors: { { weekSplit: 'weekend', state: 'default', colors: {
header: { backgroundColor: '#6a994e', color: '#ffffff' }, header: { backgroundColor: '#6a994e', color: '#ffffff' },
content: { backgroundColor: '#f1f8f4', color: '#386641' } content: { backgroundColor: '#f1f8f4', color: '#386641' }
}}, }},
{ type: 'weekend', state: 'selecting', colors: { { weekSplit: 'weekend', state: 'selecting', colors: {
header: { backgroundColor: '#95d5b2', color: '#ffffff' }, header: { backgroundColor: '#95d5b2', color: '#ffffff' },
content: { backgroundColor: '#e5f5eb', color: '#2d6a4f' } content: { backgroundColor: '#e5f5eb', color: '#2d6a4f' }
}}, }},
{ type: 'weekend', state: 'rangeStart', colors: { { weekSplit: 'weekend', state: 'rangeStart', colors: {
header: { backgroundColor: '#155d3f', color: '#ffffff' }, header: { backgroundColor: '#155d3f', color: '#ffffff' },
content: { backgroundColor: '#52b788', color: '#ffffff' } content: { backgroundColor: '#52b788', color: '#ffffff' }
}}, }},
{ type: 'weekend', state: 'rangeEnd', colors: { { weekSplit: 'weekend', state: 'rangeEnd', colors: {
header: { backgroundColor: '#155d3f', color: '#ffffff' }, header: { backgroundColor: '#155d3f', color: '#ffffff' },
content: { backgroundColor: '#52b788', color: '#ffffff' } content: { backgroundColor: '#52b788', color: '#ffffff' }
}}, }},
{ type: 'weekend', state: 'rangeMid', colors: { { weekSplit: 'weekend', state: 'rangeMid', colors: {
header: { backgroundColor: '#95d5b2', color: '#ffffff' }, header: { backgroundColor: '#95d5b2', color: '#ffffff' },
content: { backgroundColor: '#d8f3dc', color: '#155d3f' } content: { backgroundColor: '#d8f3dc', color: '#155d3f' }
}}, }},
{ type: 'weekend', state: 'active', colors: { { weekSplit: 'weekend', state: 'active', colors: {
header: { backgroundColor: '#2e7d32', color: '#ffffff' }, header: { backgroundColor: '#2e7d32', color: '#ffffff' },
content: { backgroundColor: '#4caf50', color: '#ffffff' } content: { backgroundColor: '#4caf50', color: '#ffffff' }
}} }}
@ -381,14 +397,14 @@ export const InteractiveDateRange: React.FC = () => {
<div className={styles.info} style={{ marginTop: '20px', padding: '15px', background: '#f9f9f9', borderRadius: '8px' }}> <div className={styles.info} style={{ marginTop: '20px', padding: '15px', background: '#f9f9f9', borderRadius: '8px' }}>
<h4 style={{ margin: '0 0 10px 0' }}>🎨 Color Scheme Features:</h4> <h4 style={{ margin: '0 0 10px 0' }}>🎨 Color Scheme Features:</h4>
<ul style={{ margin: '10px 0', paddingLeft: '20px' }}> <ul style={{ margin: '10px 0', paddingLeft: '20px' }}>
<li><strong>📅 Today's Date:</strong> Automatically highlighted with special colors (gold/red/green based on theme)</li> <li><strong>📅 Today's Date:</strong> Can have special colors for any state (default, active, rangeStart, etc.)</li>
<li><strong>Weekdays vs Weekends:</strong> Notice the subtle color differences</li> <li><strong>Weekdays vs Weekends:</strong> Notice the subtle color differences</li>
<li><strong>Selecting State:</strong> Hover while range is selected to see the selecting colors</li> <li><strong>Selecting State:</strong> Hover while range is selected to see the selecting colors</li>
<li><strong>Range States:</strong> Start/End dates have stronger colors than middle dates</li> <li><strong>Range States:</strong> Start/End dates have stronger colors than middle dates</li>
<li><strong>Active Dates:</strong> Click to toggle - active dates get special highlighting</li> <li><strong>Active Dates:</strong> Click to toggle - active dates get special highlighting</li>
</ul> </ul>
<p style={{ margin: '10px 0 0 0', fontSize: '0.9em', color: '#666' }}> <p style={{ margin: '10px 0 0 0', fontSize: '0.9em', color: '#666' }}>
💡 Today's date has its own distinct styling that works with all themes! 💡 Today can be in any state and still have its special styling!
</p> </p>
</div> </div>
)} )}

@ -23,7 +23,9 @@ export type {
ColorStyle, ColorStyle,
StateColors, StateColors,
DayState, DayState,
DayType WeekSplit,
DayRelative,
DayType // Deprecated, kept for backwards compatibility
} from './types/calendar'; } from './types/calendar';
// Re-export Locale type from date-fns for convenience // Re-export Locale type from date-fns for convenience

@ -32,13 +32,18 @@ export type DayState =
| 'rangeStart' | 'rangeStart'
| 'rangeEnd' | 'rangeEnd'
| 'rangeMid' | 'rangeMid'
| 'active' | 'active';
| 'today';
export type DayType = 'weekday' | 'weekend'; export type WeekSplit = 'weekday' | 'weekend';
export type DayRelative = 'today' | 'anyday';
// Keep DayType for backwards compatibility (deprecated)
export type DayType = WeekSplit;
export type ColorSchemeEntry = { export type ColorSchemeEntry = {
type: DayType; weekSplit?: WeekSplit; // Optional for backwards compatibility
type?: DayType; // Deprecated, use weekSplit
relative?: DayRelative; // Default is 'anyday'
state: DayState; state: DayState;
colors: StateColors; colors: StateColors;
}; };
@ -56,8 +61,7 @@ export type DayVariation =
| 'selecting' | 'selecting'
| 'rowStart' | 'rowStart'
| 'rowEnd' | 'rowEnd'
| 'active' | 'active';
| 'today';
export type DaySize = 'xl' | 'l' | 'm' | 's' | 'xs' | 'xxs'; export type DaySize = 'xl' | 'l' | 'm' | 's' | 'xs' | 'xxs';
export interface YearProps { export interface YearProps {

@ -1,10 +1,11 @@
import { ColorScheme, DayState, DayType, StateColors, DayVariation } from '../types/calendar'; import { ColorScheme, DayState, WeekSplit, DayRelative, StateColors, DayVariation } from '../types/calendar';
import { isToday } from './dateUtils';
/** /**
* Determines the day type based on variations (greyed indicates weekend) * Determines the week split based on variations (greyed indicates weekend)
* or by checking the day of week * or by checking the day of week
*/ */
export const getDayType = (date: Date, variations: DayVariation[], weekendDays: number[] = [6, 0]): DayType => { export const getWeekSplit = (date: Date, variations: DayVariation[], weekendDays: number[] = [6, 0]): WeekSplit => {
// If variations include 'greyed', it's a weekend // If variations include 'greyed', it's a weekend
if (variations.includes('greyed')) { if (variations.includes('greyed')) {
return 'weekend'; return 'weekend';
@ -17,8 +18,7 @@ export const getDayType = (date: Date, variations: DayVariation[], weekendDays:
* Maps variations to a DayState for color lookup * Maps variations to a DayState for color lookup
*/ */
export const getDayState = (variations: DayVariation[]): DayState => { export const getDayState = (variations: DayVariation[]): DayState => {
// Priority order for states (today has highest priority for visibility) // Priority order for states
if (variations.includes('today')) return 'today';
if (variations.includes('rangeStart') || variations.includes('rangeEnd')) { if (variations.includes('rangeStart') || variations.includes('rangeEnd')) {
if (variations.includes('rangeStart') && !variations.includes('rangeEnd')) { if (variations.includes('rangeStart') && !variations.includes('rangeEnd')) {
return 'rangeStart'; return 'rangeStart';
@ -40,34 +40,87 @@ export const getDayState = (variations: DayVariation[]): DayState => {
*/ */
export const findColorInScheme = ( export const findColorInScheme = (
colorScheme: ColorScheme | undefined, colorScheme: ColorScheme | undefined,
dayType: DayType, weekSplit: WeekSplit,
dayState: DayState dayState: DayState,
relative: DayRelative
): StateColors | undefined => { ): StateColors | undefined => {
if (!colorScheme) return undefined; if (!colorScheme) return undefined;
// First try to find exact match // First try to find exact match with all three dimensions
const exactMatch = colorScheme.find( const exactMatch = colorScheme.find(
entry => entry.type === dayType && entry.state === dayState entry => {
const entryWeekSplit = entry.weekSplit || entry.type || 'weekday';
const entryRelative = entry.relative || 'anyday';
return entryWeekSplit === weekSplit && entry.state === dayState && entryRelative === relative;
}
); );
if (exactMatch) return exactMatch.colors; if (exactMatch) return exactMatch.colors;
// If today, fallback to anyday with same weekSplit and state
if (relative === 'today') {
const anydayMatch = colorScheme.find(
entry => {
const entryWeekSplit = entry.weekSplit || entry.type || 'weekday';
const entryRelative = entry.relative || 'anyday';
return entryWeekSplit === weekSplit && entry.state === dayState && entryRelative === 'anyday';
}
);
if (anydayMatch) return anydayMatch.colors;
}
// Fallback to weekday colors for weekend if not specified // Fallback to weekday colors for weekend if not specified
if (dayType === 'weekend') { if (weekSplit === 'weekend') {
const weekdayMatch = colorScheme.find( const weekdayMatch = colorScheme.find(
entry => entry.type === 'weekday' && entry.state === dayState entry => {
const entryWeekSplit = entry.weekSplit || entry.type || 'weekday';
const entryRelative = entry.relative || 'anyday';
return entryWeekSplit === 'weekday' && entry.state === dayState && entryRelative === relative;
}
); );
if (weekdayMatch) return weekdayMatch.colors; if (weekdayMatch) return weekdayMatch.colors;
// Try weekday anyday if today weekend doesn't exist
if (relative === 'today') {
const weekdayAnydayMatch = colorScheme.find(
entry => {
const entryWeekSplit = entry.weekSplit || entry.type || 'weekday';
const entryRelative = entry.relative || 'anyday';
return entryWeekSplit === 'weekday' && entry.state === dayState && entryRelative === 'anyday';
}
);
if (weekdayAnydayMatch) return weekdayAnydayMatch.colors;
}
} }
// Fallback to default state for the day type // Fallback to default state for the same weekSplit and relative
const defaultMatch = colorScheme.find( const defaultMatch = colorScheme.find(
entry => entry.type === dayType && entry.state === 'default' entry => {
const entryWeekSplit = entry.weekSplit || entry.type || 'weekday';
const entryRelative = entry.relative || 'anyday';
return entryWeekSplit === weekSplit && entry.state === 'default' && entryRelative === relative;
}
); );
if (defaultMatch) return defaultMatch.colors; if (defaultMatch) return defaultMatch.colors;
// Final fallback to weekday default // Fallback to default anyday for the same weekSplit
if (relative === 'today') {
const defaultAnydayMatch = colorScheme.find(
entry => {
const entryWeekSplit = entry.weekSplit || entry.type || 'weekday';
const entryRelative = entry.relative || 'anyday';
return entryWeekSplit === weekSplit && entry.state === 'default' && entryRelative === 'anyday';
}
);
if (defaultAnydayMatch) return defaultAnydayMatch.colors;
}
// Final fallback to weekday default anyday
const weekdayDefault = colorScheme.find( const weekdayDefault = colorScheme.find(
entry => entry.type === 'weekday' && entry.state === 'default' entry => {
const entryWeekSplit = entry.weekSplit || entry.type || 'weekday';
const entryRelative = entry.relative || 'anyday';
return entryWeekSplit === 'weekday' && entry.state === 'default' && entryRelative === 'anyday';
}
); );
return weekdayDefault?.colors; return weekdayDefault?.colors;
}; };
@ -83,8 +136,12 @@ export const getCustomColors = (
): StateColors | undefined => { ): StateColors | undefined => {
if (!colorScheme) return undefined; if (!colorScheme) return undefined;
const dayType = getDayType(date, variations, weekendDays); const weekSplit = getWeekSplit(date, variations, weekendDays);
const dayState = getDayState(variations); const dayState = getDayState(variations);
const relative: DayRelative = isToday(date) ? 'today' : 'anyday';
return findColorInScheme(colorScheme, dayType, dayState); return findColorInScheme(colorScheme, weekSplit, dayState, relative);
}; };
// Keep old exports for backwards compatibility (deprecated)
export const getDayType = getWeekSplit;

@ -1,4 +1,7 @@
import { isSameDay, isWithinInterval, startOfDay, isToday } from 'date-fns'; import { isSameDay, isWithinInterval, startOfDay, isToday } from 'date-fns';
// Re-export isToday for use in color utils
export { isToday };
import { DateRange, DayVariation } from '../types/calendar'; import { DateRange, DayVariation } from '../types/calendar';
export const getDateVariations = ( export const getDateVariations = (
@ -9,11 +12,6 @@ export const getDateVariations = (
): DayVariation[] => { ): DayVariation[] => {
const variations: DayVariation[] = []; const variations: DayVariation[] = [];
// Check if it's today
if (isToday(date)) {
variations.push('today');
}
// Check if it's a weekend // Check if it's a weekend
if (weekendDays.includes(date.getDay())) { if (weekendDays.includes(date.getDay())) {
variations.push('greyed'); variations.push('greyed');

Loading…
Cancel
Save