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.

color swatch picker

+356 -1
+14
.cursor/rules/hip-component.mdc
··· 1 + --- 2 + alwaysApply: false 3 + --- 4 + 5 + To create a new hip component follow these steps: 6 + 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
+1 -1
README.md
··· 34 34 #### react-aria wrappers 35 35 36 36 - [ ] Color Picker 37 - - [ ] Color Swatch Picker 38 37 39 38 - [ ] Calendar 40 39 - [ ] Date Picker ··· 57 56 - [ ] Toolbar 58 57 - [ ] Toast 59 58 59 + - [x] Color Swatch Picker 60 60 - [x] Color Wheel 61 61 - [x] Color Slider 62 62 - [x] Color Area
+105
apps/docs/src/components/color-swatch-picker/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { use } from "react"; 3 + import { 4 + ColorSwatchPicker as AriaColorSwatchPicker, 5 + ColorSwatchPickerItem as AriaColorSwatchPickerItem, 6 + type ColorSwatchPickerItemProps as AriaColorSwatchPickerItemProps, 7 + type ColorSwatchPickerProps as AriaColorSwatchPickerProps, 8 + } from "react-aria-components"; 9 + 10 + import { ColorSwatch } from "../color-swatch"; 11 + import { SizeContext } from "../context"; 12 + import { radius } from "../theme/radius.stylex"; 13 + import { primaryColor, uiColor } from "../theme/semantic-color.stylex"; 14 + import { spacing } from "../theme/spacing.stylex"; 15 + import { Size, StyleXComponentProps } from "../theme/types"; 16 + 17 + const styles = stylex.create({ 18 + picker: { 19 + display: "flex", 20 + flexDirection: { 21 + default: "row", 22 + ":is([data-layout=stack])": "column", 23 + }, 24 + flexWrap: "wrap", 25 + gap: { 26 + default: spacing["2"], 27 + ":is([data-size=sm])": spacing["1"], 28 + }, 29 + }, 30 + item: { 31 + borderRadius: { 32 + ":is([data-size=sm] *)": radius.sm, 33 + ":is([data-size=md] *)": radius.md, 34 + ":is([data-size=lg] *)": radius.lg, 35 + }, 36 + boxSizing: "border-box", 37 + forcedColorAdjust: "none", 38 + outline: "none", 39 + position: "relative", 40 + width: "fit-content", 41 + 42 + borderColor: { ":is([data-selected])::after": uiColor.border3 }, 43 + borderStyle: { ":is([data-selected])::after": "solid" }, 44 + borderWidth: { ":is([data-selected])::after": 1 }, 45 + outlineColor: { ":is([data-selected])::after": "white" }, 46 + outlineOffset: { ":is([data-selected])::after": "-2px" }, 47 + outlineStyle: { ":is([data-selected])::after": "solid" }, 48 + outlineWidth: { ":is([data-selected])::after": "2px" }, 49 + "::after": { 50 + borderRadius: "inherit", 51 + boxSizing: "border-box", 52 + content: "", 53 + inset: 0, 54 + position: "absolute", 55 + }, 56 + }, 57 + }); 58 + 59 + export interface ColorSwatchPickerProps 60 + extends StyleXComponentProps<Omit<AriaColorSwatchPickerProps, "children">> { 61 + children?: React.ReactNode; 62 + layout?: "grid" | "stack"; 63 + size?: Size; 64 + } 65 + 66 + export function ColorSwatchPicker({ 67 + style, 68 + size: sizeProp, 69 + children, 70 + layout = "grid", 71 + ...props 72 + }: ColorSwatchPickerProps) { 73 + const size = sizeProp || use(SizeContext); 74 + 75 + return ( 76 + <SizeContext value={size}> 77 + <AriaColorSwatchPicker 78 + layout={layout} 79 + data-size={size} 80 + {...props} 81 + {...stylex.props(styles.picker, style)} 82 + > 83 + {children} 84 + </AriaColorSwatchPicker> 85 + </SizeContext> 86 + ); 87 + } 88 + 89 + export interface ColorSwatchPickerItemProps 90 + extends StyleXComponentProps< 91 + Omit<AriaColorSwatchPickerItemProps, "children"> 92 + > {} 93 + 94 + export function ColorSwatchPickerItem({ 95 + style, 96 + ...props 97 + }: ColorSwatchPickerItemProps) { 98 + return ( 99 + <AriaColorSwatchPickerItem {...props} {...stylex.props(styles.item, style)}> 100 + <ColorSwatch /> 101 + </AriaColorSwatchPickerItem> 102 + ); 103 + } 104 + 105 + export { ColorSwatch } from "../color-swatch";
+51
apps/docs/src/docs/components/color-swatch-picker.mdx
··· 1 + --- 2 + title: Color Swatch Picker 3 + description: A list of color swatches that allows selecting one color. 4 + --- 5 + 6 + import { PropDocs } from '../../lib/PropDocs' 7 + import { Example } from '../../lib/Example' 8 + import { Basic } from '../../examples/color-swatch-picker/basic' 9 + import { Size } from '../../examples/color-swatch-picker/size' 10 + import { Layout } from '../../examples/color-swatch-picker/layout' 11 + 12 + <Example src={Basic} /> 13 + 14 + ## Installation 15 + 16 + Run the following command to add the color swatch picker to your project. 17 + 18 + ```bash 19 + pnpm hip install color-swatch-picker 20 + ``` 21 + 22 + ## Props 23 + 24 + This component is built using the React Aria ColorSwatchPicker. 25 + See the official guide for full behavior and API details. 26 + 27 + - Docs: [React Aria ColorSwatchPicker](https://react-spectrum.adobe.com/react-aria/ColorSwatchPicker.html) 28 + 29 + <PropDocs components={["ColorSwatchPicker", "ColorSwatchPickerItem"]} /> 30 + 31 + ## Features 32 + 33 + ### Size 34 + 35 + The `ColorSwatchPicker` supports the `size` prop to adjust the size of the swatches. 36 + 37 + <Example src={Size} /> 38 + 39 + ### Layout 40 + 41 + The swatches can be laid out in a stack with `layout="stack"` 42 + 43 + <Example src={Layout} /> 44 + 45 + ## Related Components 46 + 47 + - [ColorSwatch](/docs/components/color-swatch) - For individual color previews 48 + - [ColorField](/docs/components/color-field) - For color input 49 + - [Grid](/docs/components/grid) - For arranging swatches 50 + 51 +
+16
apps/docs/src/examples/color-swatch-picker/basic.tsx
··· 1 + import { 2 + ColorSwatchPicker, 3 + ColorSwatchPickerItem, 4 + } from "@/components/color-swatch-picker"; 5 + 6 + const COLORS = ["#A00", "#f80", "#080", "#08f", "#088", "#008"] as const; 7 + 8 + export function Basic() { 9 + return ( 10 + <ColorSwatchPicker aria-label="Color choices"> 11 + {COLORS.map((c) => ( 12 + <ColorSwatchPickerItem key={c} color={c} /> 13 + ))} 14 + </ColorSwatchPicker> 15 + ); 16 + }
+27
apps/docs/src/examples/color-swatch-picker/layout.tsx
··· 1 + import { 2 + ColorSwatchPicker, 3 + ColorSwatchPickerItem, 4 + } from "@/components/color-swatch-picker"; 5 + 6 + const COLORS = [ 7 + "#A00", 8 + "#f80", 9 + "#080", 10 + "#08f", 11 + "#088", 12 + "#008", 13 + "#f0f", 14 + "#0ff", 15 + ] as const; 16 + 17 + export function Layout() { 18 + return ( 19 + <div style={{ display: "grid", gap: 12 }}> 20 + <ColorSwatchPicker aria-label="Stack layout" layout="stack"> 21 + {COLORS.map((c) => ( 22 + <ColorSwatchPickerItem key={c} color={c} /> 23 + ))} 24 + </ColorSwatchPicker> 25 + </div> 26 + ); 27 + }
+29
apps/docs/src/examples/color-swatch-picker/size.tsx
··· 1 + import { ColorSwatchPicker, ColorSwatchPickerItem } from "@/components/color-swatch-picker"; 2 + 3 + const COLORS = ["#A00", "#f80", "#080", "#08f", "#088", "#008"] as const; 4 + 5 + export function Size() { 6 + return ( 7 + <div style={{ display: "grid", gap: 12 }}> 8 + <ColorSwatchPicker aria-label="Small colors" size="sm"> 9 + {COLORS.map((c) => ( 10 + <ColorSwatchPickerItem key={c} color={c} /> 11 + ))} 12 + </ColorSwatchPicker> 13 + 14 + <ColorSwatchPicker aria-label="Medium colors" size="md"> 15 + {COLORS.map((c) => ( 16 + <ColorSwatchPickerItem key={c} color={c} /> 17 + ))} 18 + </ColorSwatchPicker> 19 + 20 + <ColorSwatchPicker aria-label="Large colors" size="lg"> 21 + {COLORS.map((c) => ( 22 + <ColorSwatchPickerItem key={c} color={c} /> 23 + ))} 24 + </ColorSwatchPicker> 25 + </div> 26 + ); 27 + } 28 + 29 +
+2
packages/hip-ui/src/cli/install.tsx
··· 19 19 import { colorAreaConfig } from "../components/color-area/color-area-config.js"; 20 20 import { colorFieldConfig } from "../components/color-field/color-field-config.js"; 21 21 import { colorSliderConfig } from "../components/color-slider/color-slider-config.js"; 22 + import { colorSwatchPickerConfig } from "../components/color-swatch-picker/color-swatch-picker-config.js"; 22 23 import { colorSwatchConfig } from "../components/color-swatch/link-config.js"; 23 24 import { colorWheelConfig } from "../components/color-wheel/color-wheel-config.js"; 24 25 import { comboboxConfig } from "../components/combobox/combobox-config.js"; ··· 116 117 colorAreaConfig, 117 118 colorSliderConfig, 118 119 colorWheelConfig, 120 + colorSwatchPickerConfig, 119 121 ]; 120 122 121 123 function StringSetting({
+6
packages/hip-ui/src/components/color-swatch-picker/color-swatch-picker-config.ts
··· 1 + import { ComponentConfig } from "../../types"; 2 + 3 + export const colorSwatchPickerConfig: ComponentConfig = { 4 + name: "color-swatch-picker", 5 + filepath: "./index.tsx", 6 + };
+105
packages/hip-ui/src/components/color-swatch-picker/index.tsx
··· 1 + import * as stylex from "@stylexjs/stylex"; 2 + import { use } from "react"; 3 + import { 4 + ColorSwatchPicker as AriaColorSwatchPicker, 5 + ColorSwatchPickerItem as AriaColorSwatchPickerItem, 6 + type ColorSwatchPickerItemProps as AriaColorSwatchPickerItemProps, 7 + type ColorSwatchPickerProps as AriaColorSwatchPickerProps, 8 + } from "react-aria-components"; 9 + 10 + import { ColorSwatch } from "../color-swatch"; 11 + import { SizeContext } from "../context"; 12 + import { radius } from "../theme/radius.stylex"; 13 + import { primaryColor, uiColor } from "../theme/semantic-color.stylex"; 14 + import { spacing } from "../theme/spacing.stylex"; 15 + import { Size, StyleXComponentProps } from "../theme/types"; 16 + 17 + const styles = stylex.create({ 18 + picker: { 19 + display: "flex", 20 + flexDirection: { 21 + default: "row", 22 + ":is([data-layout=stack])": "column", 23 + }, 24 + flexWrap: "wrap", 25 + gap: { 26 + default: spacing["2"], 27 + ":is([data-size=sm])": spacing["1"], 28 + }, 29 + }, 30 + item: { 31 + borderRadius: { 32 + ":is([data-size=sm] *)": radius.sm, 33 + ":is([data-size=md] *)": radius.md, 34 + ":is([data-size=lg] *)": radius.lg, 35 + }, 36 + boxSizing: "border-box", 37 + forcedColorAdjust: "none", 38 + outline: "none", 39 + position: "relative", 40 + width: "fit-content", 41 + 42 + borderColor: { ":is([data-selected])::after": uiColor.border3 }, 43 + borderStyle: { ":is([data-selected])::after": "solid" }, 44 + borderWidth: { ":is([data-selected])::after": 1 }, 45 + outlineColor: { ":is([data-selected])::after": "white" }, 46 + outlineOffset: { ":is([data-selected])::after": "-2px" }, 47 + outlineStyle: { ":is([data-selected])::after": "solid" }, 48 + outlineWidth: { ":is([data-selected])::after": "2px" }, 49 + "::after": { 50 + borderRadius: "inherit", 51 + boxSizing: "border-box", 52 + content: "", 53 + inset: 0, 54 + position: "absolute", 55 + }, 56 + }, 57 + }); 58 + 59 + export interface ColorSwatchPickerProps 60 + extends StyleXComponentProps<Omit<AriaColorSwatchPickerProps, "children">> { 61 + children?: React.ReactNode; 62 + layout?: "grid" | "stack"; 63 + size?: Size; 64 + } 65 + 66 + export function ColorSwatchPicker({ 67 + style, 68 + size: sizeProp, 69 + children, 70 + layout = "grid", 71 + ...props 72 + }: ColorSwatchPickerProps) { 73 + const size = sizeProp || use(SizeContext); 74 + 75 + return ( 76 + <SizeContext value={size}> 77 + <AriaColorSwatchPicker 78 + layout={layout} 79 + data-size={size} 80 + {...props} 81 + {...stylex.props(styles.picker, style)} 82 + > 83 + {children} 84 + </AriaColorSwatchPicker> 85 + </SizeContext> 86 + ); 87 + } 88 + 89 + export interface ColorSwatchPickerItemProps 90 + extends StyleXComponentProps< 91 + Omit<AriaColorSwatchPickerItemProps, "children"> 92 + > {} 93 + 94 + export function ColorSwatchPickerItem({ 95 + style, 96 + ...props 97 + }: ColorSwatchPickerItemProps) { 98 + return ( 99 + <AriaColorSwatchPickerItem {...props} {...stylex.props(styles.item, style)}> 100 + <ColorSwatch /> 101 + </AriaColorSwatchPickerItem> 102 + ); 103 + } 104 + 105 + export { ColorSwatch } from "../color-swatch";