Skip to content

Build Calendar Component Implementation#53

Open
developit wants to merge 9 commits intomainfrom
claude/implement-calendar-component-011CV5C8R5mCFFxJL9f1zxTV
Open

Build Calendar Component Implementation#53
developit wants to merge 9 commits intomainfrom
claude/implement-calendar-component-011CV5C8R5mCFFxJL9f1zxTV

Conversation

@developit
Copy link
Copy Markdown
Owner

@developit developit commented Nov 13, 2025

This pull request introduces a complete redesign and implementation of the Calendar component, transforming it from a simple input into a fully interactive calendar UI with improved accessibility, styling, and functionality. The changes include a new React/Preact-based calendar grid, navigation for months, day selection, and a corresponding update to the documentation example.

Component Implementation and API:

  • Replaces the previous input-based calendar with a new Calendar component that displays a monthly grid, supports selecting dates, and allows navigation between months. The component now accepts value and onChange props for controlled usage. (src/components/calendar/index.tsx, src/components/calendar/index.tsxL2-R172)

UI and Accessibility Enhancements:

  • Adds keyboard and mouse accessibility features, including ARIA attributes for current, selected, and disabled days, and ensures navigation buttons are focusable and visually distinct. (src/components/calendar/index.tsx, src/components/calendar/index.tsxL2-R172)

Styling Overhaul:

  • Completely revamps the calendar’s CSS for a modern, accessible, and responsive design, including distinct styles for today, selected, and disabled days, as well as improved button and header layouts. (src/components/calendar/style.css, src/components/calendar/style.cssL4-R124)

Documentation Update:

  • Updates the example in docs/examples/calendar.tsx to demonstrate the new controlled calendar usage and show the selected date, making the documentation more practical and user-friendly. (docs/examples/calendar.tsx, docs/examples/calendar.tsxR2-R26)

Replace native date input with a full inline calendar featuring:
- Semantic HTML with proper aria attributes (aria-current, aria-selected, aria-disabled)
- DOM-based month state using hidden input + command system (--prev/--next)
- CSS-driven styling with no class name concatenation
- Proper calendar grid with week headers and 6-week layout
- Visual distinction for today, selected date, and out-of-month dates
- Full keyboard navigation support with focus-visible states

The component follows PUI design patterns: minimal JS, maximum CSS, leveraging
native HTML attributes for state management instead of JavaScript state hooks.
@netlify
Copy link
Copy Markdown

netlify bot commented Nov 13, 2025

Deploy Preview for pui-demo ready!

Name Link
🔨 Latest commit 406c656
🔍 Latest deploy log https://app.netlify.com/projects/pui-demo/deploys/6915f3743360e50008341b00
😎 Deploy Preview https://deploy-preview-53--pui-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Nov 13, 2025

Size Change: +857 B (+7.59%) 🔍

Total Size: 12.1 kB

Filename Size Change
dist/index.css 6.46 kB +241 B (+3.87%)
dist/index.js 5.68 kB +616 B (+12.16%) ⚠️

compressed-size-action

claude and others added 6 commits November 13, 2025 04:16
- Add missing installCommands() call to fix --prev/--next buttons
- Use state for displayed month so re-renders happen on nav
- Replace onChange callback with hidden date input (data-date attribute)
- Dispatch change events instead of requiring manual onChange handling
- Inline calendar grid calculation for ~35% smaller component
- Remove verbose helper functions and simplify logic
- Reduce JS bundle by fixing unused code paths

Month navigation now works. Date selection via hidden input is more DOM-native
and requires no parent callback setup. Calendar can be used standalone.
Remove aria-disabled attributes and checks across all 42 day buttons. Out-of-month
dates are now clickable and fully functional, just styled without special distinction.
This trades visual separation for bundle size savings (~20 bytes gzipped).

- Remove aria-disabled checking logic from grid map
- Remove pointer-events: none from out-of-month styling
- Out-of-month dates remain clickable and valid selections
- Gzipped size: 5.73 KB (down from 5.75 KB)
…butes

Two successful optimizations for 110 bytes gzipped reduction (5.73→5.62KB):

1. Drop command/commandFor system:
   - Remove installCommands() import and call
   - Replace with direct onClick handlers on nav buttons
   - Inline nav() function to update month state directly
   - Eliminates event listener setup and command attributes

2. Remove internal p attributes:
   - Only keep p="calendar" and p="calendar-day"
   - Target internal elements with CSS selectors:
     [p="calendar"] > div:nth-of-type(N)
     [p="calendar"] > button, etc.
   - HTML output smaller, CSS selectors are well-compressed

Gzipped size: 5.62 KB (down from 5.73 KB originally, 5.75 KB with command system)
Two successful optimizations for 30 bytes gzipped reduction (5.62→5.59KB):

1. Remove hidden month input entirely:
   - Month state is already managed via useState
   - No need to persist to DOM with data-month input
   - Saves: HTML bytes, onChange handler setup, querySelector calls
   - Removes: 1 input element, 1 onChange callback

2. Remove onChange handler from data-date input:
   - We manually call setDate() on day selection
   - The onChange on data-date is never triggered/used
   - Dead code that adds unnecessary bytes
   - Just keep it as a read-only value holder

Code remains clean with array-based grid tuples [day, monthOffset]
and straightforward month navigation logic.

Gzipped size: 5.59 KB (down from 5.62 KB, originally 5.73 KB before all optimizations)
Two successful optimizations for 2 bytes gzipped reduction (5.59→5.57KB):

1. Use single-letter weekday names (S M T W T F S):
   - More compact than full names (Sun, Mon, etc.)
   - Still readable for a calendar header
   - Saves 6 bytes in source, ~1 byte in gzip

2. Simplify defaultValue parameter:
   - Use default parameter syntax: defaultValue = new Date()
   - Eliminates conditional check in useState initialization
   - Removes the ternary operator overhead
   - Saves ~1 byte in gzip

Total optimization trajectory:
- Original: 5.73 KB
- Round 1: 5.62 KB (-110 bytes: command system, p attributes)
- Round 2: 5.59 KB (-30 bytes: remove inputs, unused onChange)
- Round 3: 5.57 KB (-2 bytes: weekdays, default value)
- Total: 160 bytes saved (2.8% reduction)
@netlify
Copy link
Copy Markdown

netlify bot commented Jan 18, 2026

Deploy Preview for pui-demo ready!

Name Link
🔨 Latest commit b6d397c
🔍 Latest deploy log https://app.netlify.com/projects/pui-demo/deploys/699245c2fdbc2c00088b8f91
😎 Deploy Preview https://deploy-preview-53--pui-demo.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants