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.

date picker

+264 -23
+8 -7
.cursor/rules/hip-component.mdc
··· 5 5 To create a new hip component follow these steps: 6 6 7 7 1. First ask if there is some docs for a headless component to look at 8 - 1. create a component in packages/hip-ui/src/components 9 - 1. Create a config for that component 10 - 1. Write it's config in the new component's dir 11 - 1. Add the config to packages/hip-ui/src/cli/install 12 - 1. Run the build 13 - 1. Run `pnpm hip install --all` in the apps/docs dir 14 - 1. Generate and .mdx page with example in apps/docs 8 + 2. create a component in packages/hip-ui/src/components 9 + 3. Create a config for that component 10 + 4. Write it's config in the new component's dir 11 + 5. Add the config to packages/hip-ui/src/cli/install 12 + 6. Run the build 13 + 7. Run `pnpm hip install --all` in the apps/docs dir 14 + 8. Generate and .mdx page with example in apps/docs 15 15 16 16 ## Rules 17 17 18 18 - Prefer using packages/hip-ui/src/components/flex and packages/hip-ui/src/components/grid over css 19 19 - Use icon from lucide-react 20 + - Prefer re-using existing component rather than redefining them inside each component
+1 -1
README.md
··· 33 33 34 34 #### react-aria wrappers 35 35 36 - - [ ] Date Picker 37 36 - [ ] Range Date Picker 38 37 39 38 - [ ] Drawer ··· 53 52 - [ ] Toolbar 54 53 - [ ] Toast 55 54 55 + - [x] Date Picker 56 56 - [x] Calendar 57 57 - [x] Range Calendar 58 58 - [x] Color Picker
+1 -6
apps/docs/src/components/calendar/index.tsx
··· 28 28 } 29 29 30 30 const styles = stylex.create({ 31 - root: { 32 - display: "flex", 33 - flexDirection: "column", 34 - gap: spacing["3"], 35 - }, 36 31 header: { 37 32 alignItems: "center", 38 33 display: "flex", ··· 51 46 <AriaCalendar 52 47 visibleDuration={visibleDuration} 53 48 {...rest} 54 - {...stylex.props(styles.root, style)} 49 + {...stylex.props(calendarStyles.wrapper, style)} 55 50 > 56 51 <header {...stylex.props(styles.header)}> 57 52 <IconButton
+93
apps/docs/src/components/date-picker/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { CalendarIcon } from "lucide-react"; 3 + import { use } from "react"; 4 + import { 5 + DatePicker as AriaDatePicker, 6 + DatePickerProps as AriaDatePickerProps, 7 + DateValue, 8 + ValidationResult, 9 + Group, 10 + Dialog, 11 + Popover as AriaPopover, 12 + FieldError, 13 + } from "react-aria-components"; 14 + 15 + import Calendar, { CalendarProps } from "../calendar"; 16 + import { SizeContext } from "../context"; 17 + import { DateField } from "../date-field"; 18 + import { IconButton } from "../icon-button"; 19 + import { Description, ErrorMessage, Label } from "../label"; 20 + import { spacing } from "../theme/spacing.stylex"; 21 + import { InputVariant, Size, StyleXComponentProps } from "../theme/types"; 22 + import { useInputStyles } from "../theme/useInputStyles"; 23 + import { usePopoverStyles } from "../theme/usePopoverStyles"; 24 + 25 + export interface DatePickerProps<T extends DateValue> 26 + extends StyleXComponentProps<AriaDatePickerProps<T>>, 27 + Pick<CalendarProps<T>, "weekdayStyle" | "visibleDuration"> { 28 + label?: React.ReactNode; 29 + description?: string; 30 + errorMessage?: string | ((validation: ValidationResult) => string); 31 + size?: Size; 32 + variant?: InputVariant; 33 + } 34 + 35 + const styles = stylex.create({ 36 + popoverContent: { 37 + padding: spacing["2"], 38 + }, 39 + }); 40 + 41 + export function DatePicker<T extends DateValue>({ 42 + label, 43 + description, 44 + errorMessage, 45 + style, 46 + size: sizeProp, 47 + weekdayStyle, 48 + visibleDuration, 49 + variant, 50 + ...props 51 + }: DatePickerProps<T>) { 52 + const size = sizeProp || use(SizeContext); 53 + const inputStyles = useInputStyles({ size, variant }); 54 + const popoverStyles = usePopoverStyles(); 55 + 56 + return ( 57 + <SizeContext value={size}> 58 + <AriaDatePicker {...props} {...stylex.props(inputStyles.field, style)}> 59 + {label != null && <Label size={size}>{label}</Label>} 60 + <Group> 61 + <DateField 62 + variant={variant} 63 + suffix={ 64 + <IconButton 65 + size="sm" 66 + aria-label="Open date picker" 67 + variant="tertiary" 68 + > 69 + <CalendarIcon /> 70 + </IconButton> 71 + } 72 + /> 73 + </Group> 74 + {description && <Description size={size}>{description}</Description>} 75 + {errorMessage && ( 76 + <ErrorMessage> 77 + <FieldError>{errorMessage}</FieldError> 78 + </ErrorMessage> 79 + )} 80 + <AriaPopover 81 + {...stylex.props(popoverStyles.wrapper, popoverStyles.animation)} 82 + > 83 + <Dialog {...stylex.props(styles.popoverContent)}> 84 + <Calendar 85 + weekdayStyle={weekdayStyle} 86 + visibleDuration={visibleDuration} 87 + /> 88 + </Dialog> 89 + </AriaPopover> 90 + </AriaDatePicker> 91 + </SizeContext> 92 + ); 93 + }
+7
apps/docs/src/components/theme/useCalendarStyles.ts
··· 118 118 heading: { 119 119 fontSize: fontSize["lg"], 120 120 fontWeight: fontWeight["semibold"], 121 + margin: 0, 121 122 textAlign: "center", 122 123 }, 123 124 grid: { 124 125 borderCollapse: "collapse", 125 126 }, 127 + wrapper: { 128 + display: "flex", 129 + flexDirection: "column", 130 + gap: spacing["3"], 131 + }, 126 132 }); 127 133 128 134 // eslint-disable-next-line @eslint-react/no-unnecessary-use-prefix ··· 132 138 type: "calendar" | "range-calendar"; 133 139 }) { 134 140 return { 141 + wrapper: [styles.wrapper], 135 142 grid: [styles.grid], 136 143 heading: [styles.heading], 137 144 headerCell: [styles.headerCell],
+32
apps/docs/src/docs/components/date-picker.mdx
··· 1 + --- 2 + title: Date Picker 3 + description: A date picker combines a DateField and a Calendar popover to allow users to enter or select a date and time value. 4 + --- 5 + 6 + import { PropDocs } from '../../lib/PropDocs' 7 + import { Example } from '../../lib/Example' 8 + import { Basic } from '../../examples/date-picker/basic' 9 + 10 + <Example src={Basic} /> 11 + 12 + ## Installation 13 + 14 + Run the following command to add the date picker component to your project. 15 + 16 + ```bash 17 + pnpm hip install date-picker 18 + ``` 19 + 20 + ## Props 21 + 22 + This component is built using the [React Aria DatePicker](https://react-spectrum.adobe.com/react-aria/DatePicker.html). 23 + 24 + <PropDocs components={["DatePicker"]} /> 25 + 26 + ## Related Components 27 + 28 + - [DateField](/docs/components/date-field) - For date input without popover 29 + - [Calendar](/docs/components/calendar) - For standalone calendar display 30 + - [RangeCalendar](/docs/components/range-calendar) - For date range selection 31 + - [TimeField](/docs/components/time-field) - For time input 32 + - [Label](/docs/components/label) - For form labels and descriptions
+4 -3
apps/docs/src/examples/color-swatch-picker/size.tsx
··· 1 - import { ColorSwatchPicker, ColorSwatchPickerItem } from "@/components/color-swatch-picker"; 1 + import { 2 + ColorSwatchPicker, 3 + ColorSwatchPickerItem, 4 + } from "@/components/color-swatch-picker"; 2 5 3 6 const COLORS = ["#A00", "#f80", "#080", "#08f", "#088", "#008"] as const; 4 7 ··· 25 28 </div> 26 29 ); 27 30 } 28 - 29 -
+5
apps/docs/src/examples/date-picker/basic.tsx
··· 1 + import { DatePicker } from "@/components/date-picker"; 2 + 3 + export function Basic() { 4 + return <DatePicker label="Date" />; 5 + }
+2
packages/hip-ui/src/cli/install.tsx
··· 28 28 import { commandMenuConfig } from "../components/command-menu/command-menu-config.js"; 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 + import { datePickerConfig } from "../components/date-picker/date-picker-config.js"; 31 32 import { dialogConfig } from "../components/dialog/dialog-config.js"; 32 33 import { fileDropZoneConfig } from "../components/file-drop-zone/file-drop-zone-config.js"; 33 34 import { flexConfig } from "../components/flex/flex-config.js"; ··· 92 93 contextMenuConfig, 93 94 timeFieldConfig, 94 95 dateFieldConfig, 96 + datePickerConfig, 95 97 searchFieldConfig, 96 98 colorFieldConfig, 97 99 numberFieldConfig,
+1 -6
packages/hip-ui/src/components/calendar/index.tsx
··· 28 28 } 29 29 30 30 const styles = stylex.create({ 31 - root: { 32 - display: "flex", 33 - flexDirection: "column", 34 - gap: spacing["3"], 35 - }, 36 31 header: { 37 32 alignItems: "center", 38 33 display: "flex", ··· 51 46 <AriaCalendar 52 47 visibleDuration={visibleDuration} 53 48 {...rest} 54 - {...stylex.props(styles.root, style)} 49 + {...stylex.props(calendarStyles.wrapper, style)} 55 50 > 56 51 <header {...stylex.props(styles.header)}> 57 52 <IconButton
+10
packages/hip-ui/src/components/date-picker/date-picker-config.ts
··· 1 + import { ComponentConfig } from "../../types"; 2 + 3 + export const datePickerConfig: ComponentConfig = { 4 + name: "date-picker", 5 + filepath: "./index.tsx", 6 + hipDependencies: [ 7 + "../theme/useInputStyles.ts", 8 + "../theme/useCalendarStyles.ts", 9 + ], 10 + };
+93
packages/hip-ui/src/components/date-picker/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { CalendarIcon } from "lucide-react"; 3 + import { use } from "react"; 4 + import { 5 + DatePicker as AriaDatePicker, 6 + DatePickerProps as AriaDatePickerProps, 7 + DateValue, 8 + ValidationResult, 9 + Group, 10 + Dialog, 11 + Popover as AriaPopover, 12 + FieldError, 13 + } from "react-aria-components"; 14 + 15 + import Calendar, { CalendarProps } from "../calendar"; 16 + import { SizeContext } from "../context"; 17 + import { DateField } from "../date-field"; 18 + import { IconButton } from "../icon-button"; 19 + import { Description, ErrorMessage, Label } from "../label"; 20 + import { spacing } from "../theme/spacing.stylex"; 21 + import { InputVariant, Size, StyleXComponentProps } from "../theme/types"; 22 + import { useInputStyles } from "../theme/useInputStyles"; 23 + import { usePopoverStyles } from "../theme/usePopoverStyles"; 24 + 25 + export interface DatePickerProps<T extends DateValue> 26 + extends StyleXComponentProps<AriaDatePickerProps<T>>, 27 + Pick<CalendarProps<T>, "weekdayStyle" | "visibleDuration"> { 28 + label?: React.ReactNode; 29 + description?: string; 30 + errorMessage?: string | ((validation: ValidationResult) => string); 31 + size?: Size; 32 + variant?: InputVariant; 33 + } 34 + 35 + const styles = stylex.create({ 36 + popoverContent: { 37 + padding: spacing["2"], 38 + }, 39 + }); 40 + 41 + export function DatePicker<T extends DateValue>({ 42 + label, 43 + description, 44 + errorMessage, 45 + style, 46 + size: sizeProp, 47 + weekdayStyle, 48 + visibleDuration, 49 + variant, 50 + ...props 51 + }: DatePickerProps<T>) { 52 + const size = sizeProp || use(SizeContext); 53 + const inputStyles = useInputStyles({ size, variant }); 54 + const popoverStyles = usePopoverStyles(); 55 + 56 + return ( 57 + <SizeContext value={size}> 58 + <AriaDatePicker {...props} {...stylex.props(inputStyles.field, style)}> 59 + {label != null && <Label size={size}>{label}</Label>} 60 + <Group> 61 + <DateField 62 + variant={variant} 63 + suffix={ 64 + <IconButton 65 + size="sm" 66 + aria-label="Open date picker" 67 + variant="tertiary" 68 + > 69 + <CalendarIcon /> 70 + </IconButton> 71 + } 72 + /> 73 + </Group> 74 + {description && <Description size={size}>{description}</Description>} 75 + {errorMessage && ( 76 + <ErrorMessage> 77 + <FieldError>{errorMessage}</FieldError> 78 + </ErrorMessage> 79 + )} 80 + <AriaPopover 81 + {...stylex.props(popoverStyles.wrapper, popoverStyles.animation)} 82 + > 83 + <Dialog {...stylex.props(styles.popoverContent)}> 84 + <Calendar 85 + weekdayStyle={weekdayStyle} 86 + visibleDuration={visibleDuration} 87 + /> 88 + </Dialog> 89 + </AriaPopover> 90 + </AriaDatePicker> 91 + </SizeContext> 92 + ); 93 + }
+7
packages/hip-ui/src/components/theme/useCalendarStyles.ts
··· 118 118 heading: { 119 119 fontSize: fontSize["lg"], 120 120 fontWeight: fontWeight["semibold"], 121 + margin: 0, 121 122 textAlign: "center", 122 123 }, 123 124 grid: { 124 125 borderCollapse: "collapse", 125 126 }, 127 + wrapper: { 128 + display: "flex", 129 + flexDirection: "column", 130 + gap: spacing["3"], 131 + }, 126 132 }); 127 133 128 134 // eslint-disable-next-line @eslint-react/no-unnecessary-use-prefix ··· 132 138 type: "calendar" | "range-calendar"; 133 139 }) { 134 140 return { 141 + wrapper: [styles.wrapper], 135 142 grid: [styles.grid], 136 143 heading: [styles.heading], 137 144 headerCell: [styles.headerCell],