Commit 75ced68
authored
feat(registry): add time-picker (#193)
* feat: add time-picker component
- Add TypeScript types with comprehensive interfaces
- Create time-picker UI component with hour, minute, second selection
- Support both 12-hour and 24-hour formats
- Add 6 demo examples (basic, 12-hour, seconds, controlled, form, step)
- Include full documentation with API reference and keyboard shortcuts
- Update registry-ui.ts and registry-examples.ts
- Add form integration with validation support
- Include customizable step intervals for time selection
* feat(time-picker): refactor with native behavior and React 19 patterns
- Add native HTML time input behavior (click to select segments)
- Implement inline editing with arrow key navigation (↑↓ to change values)
- Add AM/PM support with instant keyboard shortcuts (A/P keys)
- Introduce InputGroup pattern for cleaner, composable API
- Remove forwardRef in favor of React 19 direct ref props
- Memoize callbacks and compose event handlers properly
- Add arrow key navigation in dropdown columns with wrapping
- Simplify all examples to use new InputGroup pattern
- Update documentation with keyboard shortcuts and usage examples
Breaking changes:
- InputGroup now wraps inputs and trigger together
- Trigger is now a button that goes inside InputGroup
- Removed separate inline demo examples (all use same pattern)
* refactor(time-picker): use shadcn Popover with anchor positioning
- Replace custom popover implementation with shadcn Popover components
- Use PopoverAnchor to position popover relative to InputGroup
- Leverage Radix CSS variables (--radix-popover-trigger-width) for width
- Fix store context issue by splitting Root into Root/RootImpl pattern
- Remove manual width measurement and useEffect
- Improve accessibility and positioning consistency
* reactor: api
* feat: better demo
* refactor: improve time-picker and color-picker components
- Add open/defaultOpen props to time-picker for controlled state
- Fix duplicate hour key bug in 12-hour format
- Refactor time-picker store to inline pattern (matches stepper)
- Optimize column items with getItems() pattern for better performance
- Add use12Hours demo to show period functionality
- Refactor color-picker store to inline pattern
- Remove redundant onOpenChange callback in color-picker
- Fix CSS linter warning in color-picker
* feat(time-picker): add visually hidden scrollbar
* fix(time-picker): auto-focus selected item when popover opens
* fix(time-picker): use onOpenAutoFocus for better focus management
* feat(time-picker): add group context and Tab navigation between columns
* feat(time-picker): add Tab navigation support for AM/PM column
* fix(time-picker): properly track period item refs for Tab navigation
* refactor(time-picker): use TimePickerColumn for Period component, make components reusable
* debug(time-picker): add console logs for focus debugging
* fix(time-picker): stabilize getSelectedItemRef to prevent re-registrations
* debug(time-picker): add onFocus logs to track focus events
* feat(time-picker): add Left/Right arrow navigation between columns
* chore(time-picker): remove all debug console.logs
* refactor: update time-picker-form-demo to use shadcn form pattern
* chore: update page
* refactor(time-picker): replace use12Hours with locale-based auto-detection
- Replace use12Hours prop with optional locale prop
- Add uses12HourFormat() utility using Intl.DateTimeFormat
- Calculate is12Hour once in root and share via context for better performance
- Always store values in 24-hour format (HH:mm or HH:mm:ss) internally
- Auto-detect display format from user's locale, matching native input behavior
- Remove time-picker-12hour-demo (no longer needed with auto-detection)
- Update documentation and examples
- Rename time-picker-step-demo to time-picker-minute-step-demo for clarity
* refine time-picker segments styling: make more compact and less blocky
* fix time-picker empty state: show '--' placeholders instead of blank segments
* feat: display placeholder text in time-picker when no value is set
* fix time-picker: prevent auto-fill on blur and fix placeholder overlap
* chore: revert
* refactor(time-picker): improve focus management and registration flow
- Add focusFirst utility for fallback focus strategy when no value is set
- Fix focus management when value/defaultValue is empty
- Consolidate redundant types (ItemData, ColumnData) at top of file
- Create reusable sortNodes utility for DOM position sorting
- Simplify column registration to use ColumnData object instead of flat params
- Add proper error handling to useTimePickerGroupContext hook
- Optimize getSelectedItemRef to reuse getItems() (DRY principle)
- Add COLUMN_NAME constant for consistency
- Add SegmentFormat type alias for better type reusability
- Remove redundant comments and clean up code structure
- Match stepper component's cleaner, more performant patterns
* chore: build registry
* chore: update docs
* feat(time-picker): add -- placeholder for empty segments
- Show -- placeholder in each segment when no value (matches native HTML time input)
- Keep -- visible and selected on focus for better UX
- Handle arrow key navigation from -- placeholder state
* feat(time-picker): initialize with current time when opening popover
- When popover opens with no value/defaultValue, initialize with current time
- Matches native HTML time input behavior
- Selecting hour preserves current minutes/seconds from initialization
* chore: revert
* feat(time-picker): show current time as reference when no value set
- Display current time in columns when no value/defaultValue is set
- Use current time segments as defaults when user selects a segment
- Matches HTML time input behavior (visual reference only, no auto-update)
- When selecting hour=8 at current time 2:30 PM, creates '8:30'
- Applies to hours, minutes, seconds, and AM/PM period
* fix(time-picker): Tab navigation skipping columns
- Replace focusFirst with direct focus for Tab/Arrow column navigation
- Fixes timing conflicts between browser Tab behavior and custom handler
- Tab now consistently moves to the next/previous column without skipping
* chore: revert again
* fix: focus ring
* fix(time-picker): resolve inconsistent tab focus navigation between columns
- Added queueMicrotask to ensure DOM stability before column navigation
- Added safety checks for column existence and valid refs
- Tab navigation now consistently moves between columns (Hour → Minute → Period)
- Arrow key navigation remains unchanged and working correctly
* fix(time-picker): prevent column items from being cut off during scroll
- Changed scrollIntoView from 'block: nearest' to 'block: center'
- Selected items now center in viewport, ensuring full visibility
- Eliminates partial clipping at container edges
* chore: build registry
* feat: native like
* feat(time-picker): implement native HTML time input behavior
- Auto-pad single digits (1 -> 01) with instant display
- Auto-advance to next segment after two digits
- Smart digit combination (typing 1 then 1 makes 11)
- Keep segments empty (--) until explicitly set
- Support partial time values (10:-- instead of 10:00)
- Fix period segment to stay empty until user sets it
- Add keyboard shortcuts for period: A/P/1/2 keys, arrow up/down
- Preserve selection state after period changes
- Use refs-based input registry instead of querySelector
- Match native HTML time input behavior exactly
* feat: add arrow left and arrow right navigation
* feat(time-picker): add arrow navigation and backspace to clear segments
- Add left/right arrow keys to navigate between segments
- Add backspace/delete to clear selected segment
- Preserve selection after clearing segment
- Fix selection state to match native HTML time input
- Improve accessibility with full keyboard navigation support
* docs(time-picker): update accessibility and keyboard interaction documentation
- Add comprehensive keyboard shortcuts organized by category
- Document all input navigation options (Tab, Arrow keys)
- Add value editing shortcuts (digits, arrows, backspace/delete)
- Document period (AM/PM) shortcuts (A/P/1/2, arrows)
- Update notes section with detailed behavior explanations
- Organize documentation into Behavior, Format & Locale, and Customization sections
* refactor(time-picker): clean up input group context naming and structure
- Rename InputRegistryContext to TimePickerInputGroupContext
- Add proper error handling with context validation
- Inline provider logic directly in TimePickerInputGroup component
- Rename methods to onInputRegister/onInputUnregister for consistency
- Use InputElement type alias instead of HTMLInputElement
- Replace useEffect with useIsomorphicLayoutEffect for input registration
* feat(time-picker): add customizable segment placeholders and cleanup
- Add segmentPlaceholder prop to customize empty segment display
- Supports string (e.g., "--") or object (e.g., { hour: "hh", minute: "mm", period: "aa" })
- Normalized internally to object format for consistency
- Remove unused placeholder prop
- Clean up redundant comments (71 → 1)
- Fix input width to dynamically adjust based on placeholder length
- Add inputMode, autoComplete, and aria-invalid attributes to prevent browser validation errors
- Update demo to show custom placeholder format
* feat: add placeholder demo
* feat: update css variables
* feat: update docs
* fix(time-picker): period column width, blur reset, and arrow navigation
- Increase period column width to prevent text cutoff
- Fix period value reset on blur by deriving from hour value
- Fix arrow key navigation in popover by properly selecting current period
- Default to current time's AM/PM when no value is set
* feat(time-picker): auto-fill missing segments with current time
- Auto-fill missing hour/minute/second when selecting any segment
- Works in both input fields (on blur) and popover columns (on select)
- Matches HTML native time input behavior
- Missing segments populate with current time values
* refactor: ad dconst
* refactor(time-picker): use DEFAULT_SEGMENT_PLACEHOLDER constant
Replace all hardcoded "--" strings with DEFAULT_SEGMENT_PLACEHOLDER constant for better maintainability and consistency.
* refactor: time picker const1 parent cc0b56d commit 75ced68
File tree
31 files changed
+3750
-436
lines changed- docs
- __registry__
- app/(lobby)/pg
- content/docs/components
- public/r
- styles/default
- registry
- default
- examples
- ui
- styles
- types/docs
31 files changed
+3750
-436
lines changedLarge diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
1 | 3 | | |
2 | 4 | | |
3 | 5 | | |
4 | | - | |
5 | | - | |
6 | | - | |
7 | | - | |
8 | | - | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
13 | 13 | | |
14 | | - | |
15 | | - | |
16 | | - | |
17 | | - | |
18 | | - | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
19 | 20 | | |
20 | 21 | | |
21 | 22 | | |
| |||
0 commit comments