A design system in a box. hip-ui.tngl.io/docs/introduction
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

range picker

+344 -8
+1 -2
README.md
··· 33 33 34 34 #### react-aria wrappers 35 35 36 - - [ ] Range Date Picker 37 - 38 36 - [ ] Drawer 39 37 - [ ] Sheet 40 38 ··· 52 50 - [ ] Toolbar 53 51 - [ ] Toast 54 52 53 + - [x] Range Date Picker 55 54 - [x] Date Picker 56 55 - [x] Calendar 57 56 - [x] Range Calendar
-2
apps/docs/src/components/calendar/index.tsx
··· 93 93 </AriaCalendar> 94 94 ); 95 95 } 96 - 97 - export default Calendar;
+1 -1
apps/docs/src/components/date-picker/index.tsx
··· 12 12 FieldError, 13 13 } from "react-aria-components"; 14 14 15 - import Calendar, { CalendarProps } from "../calendar"; 15 + import { Calendar, CalendarProps } from "../calendar"; 16 16 import { SizeContext } from "../context"; 17 17 import { DateField } from "../date-field"; 18 18 import { IconButton } from "../icon-button";
+145
apps/docs/src/components/date-range-picker/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { CalendarIcon } from "lucide-react"; 3 + import { use } from "react"; 4 + import { 5 + DateRangePicker as AriaDateRangePicker, 6 + DateRangePickerProps as AriaDateRangePickerProps, 7 + DateValue, 8 + ValidationResult, 9 + Group, 10 + Dialog, 11 + Popover as AriaPopover, 12 + FieldError, 13 + DateInput, 14 + DateSegment, 15 + } from "react-aria-components"; 16 + 17 + import { SizeContext } from "../context"; 18 + import { IconButton } from "../icon-button"; 19 + import { Description, ErrorMessage, Label } from "../label"; 20 + import { RangeCalendar, RangeCalendarProps } from "../range-calendar"; 21 + import { uiColor } from "../theme/semantic-color.stylex"; 22 + import { spacing } from "../theme/spacing.stylex"; 23 + import { InputVariant, Size, StyleXComponentProps } from "../theme/types"; 24 + import { fontSize } from "../theme/typography.stylex"; 25 + import { useInputStyles } from "../theme/useInputStyles"; 26 + import { usePopoverStyles } from "../theme/usePopoverStyles"; 27 + 28 + export interface DateRangePickerProps<T extends DateValue> 29 + extends StyleXComponentProps<AriaDateRangePickerProps<T>>, 30 + Pick<RangeCalendarProps<T>, "weekdayStyle" | "visibleDuration"> { 31 + label?: React.ReactNode; 32 + description?: string; 33 + errorMessage?: string | ((validation: ValidationResult) => string); 34 + size?: Size; 35 + variant?: InputVariant; 36 + } 37 + 38 + const styles = stylex.create({ 39 + group: { 40 + alignItems: "center", 41 + display: "flex", 42 + gap: spacing["1"], 43 + 44 + fontSize: { 45 + ":is([data-size=sm])": fontSize["xs"], 46 + ":is([data-size=md])": fontSize["sm"], 47 + ":is([data-size=lg])": fontSize["base"], 48 + }, 49 + }, 50 + popoverContent: { 51 + padding: spacing["2"], 52 + }, 53 + separator: { 54 + paddingRight: { 55 + ":is([data-size=sm] *)": spacing["1"], 56 + ":is([data-size=md] *)": spacing["2"], 57 + ":is([data-size=lg] *)": spacing["1"], 58 + }, 59 + }, 60 + lastInput: { 61 + paddingRight: 0, 62 + }, 63 + segment: { 64 + color: { 65 + ":is([data-placeholder])": uiColor.text1, 66 + }, 67 + }, 68 + }); 69 + 70 + export function DateRangePicker<T extends DateValue>({ 71 + label, 72 + description, 73 + errorMessage, 74 + style, 75 + size: sizeProp, 76 + weekdayStyle, 77 + visibleDuration, 78 + variant, 79 + ...props 80 + }: DateRangePickerProps<T>) { 81 + const size = sizeProp || use(SizeContext); 82 + const inputStyles = useInputStyles({ size, variant }); 83 + const popoverStyles = usePopoverStyles(); 84 + 85 + return ( 86 + <SizeContext value={size}> 87 + <AriaDateRangePicker 88 + {...props} 89 + {...stylex.props(inputStyles.field, style)} 90 + > 91 + {label != null && <Label size={size}>{label}</Label>} 92 + <Group 93 + data-size={size} 94 + {...stylex.props(inputStyles.wrapper, styles.group)} 95 + > 96 + <DateInput slot="start" {...stylex.props(inputStyles.input)}> 97 + {(segment) => ( 98 + <DateSegment 99 + segment={segment} 100 + {...stylex.props(styles.segment)} 101 + /> 102 + )} 103 + </DateInput> 104 + <div aria-hidden="true" {...stylex.props(styles.separator)}> 105 + - 106 + </div> 107 + <DateInput 108 + slot="end" 109 + {...stylex.props(inputStyles.input, styles.lastInput)} 110 + > 111 + {(segment) => ( 112 + <DateSegment 113 + segment={segment} 114 + {...stylex.props(styles.segment)} 115 + /> 116 + )} 117 + </DateInput> 118 + <IconButton 119 + size="sm" 120 + aria-label="Open date picker" 121 + variant="tertiary" 122 + > 123 + <CalendarIcon /> 124 + </IconButton> 125 + </Group> 126 + {description && <Description size={size}>{description}</Description>} 127 + {errorMessage && ( 128 + <ErrorMessage> 129 + <FieldError>{errorMessage}</FieldError> 130 + </ErrorMessage> 131 + )} 132 + <AriaPopover 133 + {...stylex.props(popoverStyles.wrapper, popoverStyles.animation)} 134 + > 135 + <Dialog {...stylex.props(styles.popoverContent)}> 136 + <RangeCalendar 137 + weekdayStyle={weekdayStyle} 138 + visibleDuration={visibleDuration} 139 + /> 140 + </Dialog> 141 + </AriaPopover> 142 + </AriaDateRangePicker> 143 + </SizeContext> 144 + ); 145 + }
+33
apps/docs/src/docs/components/date-range-picker.mdx
··· 1 + --- 2 + title: Date Range Picker 3 + description: A date range picker combines date inputs and a RangeCalendar popover to allow users to enter or select a date range. 4 + --- 5 + 6 + import { PropDocs } from '../../lib/PropDocs' 7 + import { Example } from '../../lib/Example' 8 + import { Basic } from '../../examples/date-range-picker/basic' 9 + 10 + <Example src={Basic} /> 11 + 12 + ## Installation 13 + 14 + Run the following command to add the date range picker component to your project. 15 + 16 + ```bash 17 + pnpm hip install date-range-picker 18 + ``` 19 + 20 + ## Props 21 + 22 + This component is built using the [React Aria DateRangePicker](https://react-spectrum.adobe.com/react-aria/DateRangePicker.html). 23 + 24 + <PropDocs components={["DateRangePicker"]} /> 25 + 26 + ## Related Components 27 + 28 + - [DatePicker](/docs/components/date-picker) - For single date selection 29 + - [RangeCalendar](/docs/components/range-calendar) - For standalone range calendar display 30 + - [DateField](/docs/components/date-field) - For date input without popover 31 + - [TimeField](/docs/components/time-field) - For time input 32 + - [Label](/docs/components/label) - For form labels and descriptions 33 +
+6
apps/docs/src/examples/date-range-picker/basic.tsx
··· 1 + import { DateRangePicker } from "@/components/date-range-picker"; 2 + 3 + export function Basic() { 4 + return <DateRangePicker label="Date Range" />; 5 + } 6 +
+2
packages/hip-ui/src/cli/install.tsx
··· 29 29 import { contextMenuConfig } from "../components/context-menu/context-menu-config.js"; 30 30 import { dateFieldConfig } from "../components/date-field/date-field-config.js"; 31 31 import { datePickerConfig } from "../components/date-picker/date-picker-config.js"; 32 + import { dateRangePickerConfig } from "../components/date-range-picker/date-range-picker-config.js"; 32 33 import { dialogConfig } from "../components/dialog/dialog-config.js"; 33 34 import { fileDropZoneConfig } from "../components/file-drop-zone/file-drop-zone-config.js"; 34 35 import { flexConfig } from "../components/flex/flex-config.js"; ··· 94 95 timeFieldConfig, 95 96 dateFieldConfig, 96 97 datePickerConfig, 98 + dateRangePickerConfig, 97 99 searchFieldConfig, 98 100 colorFieldConfig, 99 101 numberFieldConfig,
-2
packages/hip-ui/src/components/calendar/index.tsx
··· 93 93 </AriaCalendar> 94 94 ); 95 95 } 96 - 97 - export default Calendar;
+1 -1
packages/hip-ui/src/components/date-picker/index.tsx
··· 12 12 FieldError, 13 13 } from "react-aria-components"; 14 14 15 - import Calendar, { CalendarProps } from "../calendar"; 15 + import { Calendar, CalendarProps } from "../calendar"; 16 16 import { SizeContext } from "../context"; 17 17 import { DateField } from "../date-field"; 18 18 import { IconButton } from "../icon-button";
+10
packages/hip-ui/src/components/date-range-picker/date-range-picker-config.ts
··· 1 + import { ComponentConfig } from "../../types"; 2 + 3 + export const dateRangePickerConfig: ComponentConfig = { 4 + name: "date-range-picker", 5 + filepath: "./index.tsx", 6 + hipDependencies: [ 7 + "../theme/useInputStyles.ts", 8 + "../theme/usePopoverStyles.ts", 9 + ], 10 + };
+145
packages/hip-ui/src/components/date-range-picker/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { CalendarIcon } from "lucide-react"; 3 + import { use } from "react"; 4 + import { 5 + DateRangePicker as AriaDateRangePicker, 6 + DateRangePickerProps as AriaDateRangePickerProps, 7 + DateValue, 8 + ValidationResult, 9 + Group, 10 + Dialog, 11 + Popover as AriaPopover, 12 + FieldError, 13 + DateInput, 14 + DateSegment, 15 + } from "react-aria-components"; 16 + 17 + import { SizeContext } from "../context"; 18 + import { IconButton } from "../icon-button"; 19 + import { Description, ErrorMessage, Label } from "../label"; 20 + import { RangeCalendar, RangeCalendarProps } from "../range-calendar"; 21 + import { uiColor } from "../theme/semantic-color.stylex"; 22 + import { spacing } from "../theme/spacing.stylex"; 23 + import { InputVariant, Size, StyleXComponentProps } from "../theme/types"; 24 + import { fontSize } from "../theme/typography.stylex"; 25 + import { useInputStyles } from "../theme/useInputStyles"; 26 + import { usePopoverStyles } from "../theme/usePopoverStyles"; 27 + 28 + export interface DateRangePickerProps<T extends DateValue> 29 + extends StyleXComponentProps<AriaDateRangePickerProps<T>>, 30 + Pick<RangeCalendarProps<T>, "weekdayStyle" | "visibleDuration"> { 31 + label?: React.ReactNode; 32 + description?: string; 33 + errorMessage?: string | ((validation: ValidationResult) => string); 34 + size?: Size; 35 + variant?: InputVariant; 36 + } 37 + 38 + const styles = stylex.create({ 39 + group: { 40 + alignItems: "center", 41 + display: "flex", 42 + gap: spacing["1"], 43 + 44 + fontSize: { 45 + ":is([data-size=sm])": fontSize["xs"], 46 + ":is([data-size=md])": fontSize["sm"], 47 + ":is([data-size=lg])": fontSize["base"], 48 + }, 49 + }, 50 + popoverContent: { 51 + padding: spacing["2"], 52 + }, 53 + separator: { 54 + paddingRight: { 55 + ":is([data-size=sm] *)": spacing["1"], 56 + ":is([data-size=md] *)": spacing["2"], 57 + ":is([data-size=lg] *)": spacing["1"], 58 + }, 59 + }, 60 + lastInput: { 61 + paddingRight: 0, 62 + }, 63 + segment: { 64 + color: { 65 + ":is([data-placeholder])": uiColor.text1, 66 + }, 67 + }, 68 + }); 69 + 70 + export function DateRangePicker<T extends DateValue>({ 71 + label, 72 + description, 73 + errorMessage, 74 + style, 75 + size: sizeProp, 76 + weekdayStyle, 77 + visibleDuration, 78 + variant, 79 + ...props 80 + }: DateRangePickerProps<T>) { 81 + const size = sizeProp || use(SizeContext); 82 + const inputStyles = useInputStyles({ size, variant }); 83 + const popoverStyles = usePopoverStyles(); 84 + 85 + return ( 86 + <SizeContext value={size}> 87 + <AriaDateRangePicker 88 + {...props} 89 + {...stylex.props(inputStyles.field, style)} 90 + > 91 + {label != null && <Label size={size}>{label}</Label>} 92 + <Group 93 + data-size={size} 94 + {...stylex.props(inputStyles.wrapper, styles.group)} 95 + > 96 + <DateInput slot="start" {...stylex.props(inputStyles.input)}> 97 + {(segment) => ( 98 + <DateSegment 99 + segment={segment} 100 + {...stylex.props(styles.segment)} 101 + /> 102 + )} 103 + </DateInput> 104 + <div aria-hidden="true" {...stylex.props(styles.separator)}> 105 + - 106 + </div> 107 + <DateInput 108 + slot="end" 109 + {...stylex.props(inputStyles.input, styles.lastInput)} 110 + > 111 + {(segment) => ( 112 + <DateSegment 113 + segment={segment} 114 + {...stylex.props(styles.segment)} 115 + /> 116 + )} 117 + </DateInput> 118 + <IconButton 119 + size="sm" 120 + aria-label="Open date picker" 121 + variant="tertiary" 122 + > 123 + <CalendarIcon /> 124 + </IconButton> 125 + </Group> 126 + {description && <Description size={size}>{description}</Description>} 127 + {errorMessage && ( 128 + <ErrorMessage> 129 + <FieldError>{errorMessage}</FieldError> 130 + </ErrorMessage> 131 + )} 132 + <AriaPopover 133 + {...stylex.props(popoverStyles.wrapper, popoverStyles.animation)} 134 + > 135 + <Dialog {...stylex.props(styles.popoverContent)}> 136 + <RangeCalendar 137 + weekdayStyle={weekdayStyle} 138 + visibleDuration={visibleDuration} 139 + /> 140 + </Dialog> 141 + </AriaPopover> 142 + </AriaDateRangePicker> 143 + </SizeContext> 144 + ); 145 + }