| b69ab31 | | | 1 | /** |
| b69ab31 | | | 2 | * Copyright (c) Meta Platforms, Inc. and affiliates. |
| b69ab31 | | | 3 | * |
| b69ab31 | | | 4 | * This source code is licensed under the MIT license found in the |
| b69ab31 | | | 5 | * LICENSE file in the root directory of this source tree. |
| b69ab31 | | | 6 | */ |
| b69ab31 | | | 7 | |
| b69ab31 | | | 8 | import type {StyleXVar} from '@stylexjs/stylex/lib/StyleXTypes'; |
| b69ab31 | | | 9 | |
| b69ab31 | | | 10 | import * as stylex from '@stylexjs/stylex'; |
| b69ab31 | | | 11 | import {useState, type ReactNode} from 'react'; |
| b69ab31 | | | 12 | import {Badge} from '../Badge'; |
| b69ab31 | | | 13 | import {Banner, BannerKind} from '../Banner'; |
| b69ab31 | | | 14 | import {Button} from '../Button'; |
| b69ab31 | | | 15 | import {ButtonDropdown} from '../ButtonDropdown'; |
| b69ab31 | | | 16 | import {ButtonGroup} from '../ButtonGroup'; |
| b69ab31 | | | 17 | import {Checkbox} from '../Checkbox'; |
| b69ab31 | | | 18 | import {Divider} from '../Divider'; |
| b69ab31 | | | 19 | import {Dropdown} from '../Dropdown'; |
| b69ab31 | | | 20 | import {ErrorNotice} from '../ErrorNotice'; |
| b69ab31 | | | 21 | import {HorizontallyGrowingTextField} from '../HorizontallyGrowingTextField'; |
| b69ab31 | | | 22 | import {Icon} from '../Icon'; |
| b69ab31 | | | 23 | import {Kbd} from '../Kbd'; |
| b69ab31 | | | 24 | import {KeyCode, Modifier} from '../KeyboardShortcuts'; |
| b69ab31 | | | 25 | import {Panels} from '../Panels'; |
| b69ab31 | | | 26 | import {RadioGroup} from '../Radio'; |
| b69ab31 | | | 27 | import {Subtle} from '../Subtle'; |
| b69ab31 | | | 28 | import {Tag} from '../Tag'; |
| b69ab31 | | | 29 | import {TextArea} from '../TextArea'; |
| b69ab31 | | | 30 | import {TextField} from '../TextField'; |
| b69ab31 | | | 31 | import {Tooltip} from '../Tooltip'; |
| b69ab31 | | | 32 | import {Typeahead} from '../Typeahead'; |
| b69ab31 | | | 33 | import {layout} from '../theme/layout'; |
| b69ab31 | | | 34 | import {colors, font, radius, spacing} from '../theme/tokens.stylex'; |
| b69ab31 | | | 35 | |
| b69ab31 | | | 36 | /* eslint-disable no-console */ |
| b69ab31 | | | 37 | |
| b69ab31 | | | 38 | const basicBgs = ['bg', 'subtleHoverDarken', 'hoverDarken'] as const; |
| b69ab31 | | | 39 | const pureColors = ['red', 'yellow', 'orange', 'green', 'blue', 'purple', 'grey'] as const; |
| b69ab31 | | | 40 | const scmColors = ['modifiedFg', 'addedFg', 'removedFg', 'missingFg'] as const; |
| b69ab31 | | | 41 | const signalColors = ['signalGoodBg', 'signalMediumBg', 'signalBadBg'] as const; |
| b69ab31 | | | 42 | const paddings = ['none', 'quarter', 'half', 'pad', 'double', 'xlarge'] as const; |
| b69ab31 | | | 43 | const fontSizes = ['smaller', 'small', 'normal', 'big', 'bigger'] as const; |
| b69ab31 | | | 44 | |
| b69ab31 | | | 45 | export default function ComponentExplorer() { |
| b69ab31 | | | 46 | const [radioChoice, setRadioChoice] = useState('radio'); |
| b69ab31 | | | 47 | const [checkbox1, setCheckbox1] = useState(false); |
| b69ab31 | | | 48 | const [checkbox2, setCheckbox2] = useState(true); |
| b69ab31 | | | 49 | const [dropdownChoice, setDropdownChoice] = useState('B'); |
| b69ab31 | | | 50 | const buttonDropdownOptions = [ |
| b69ab31 | | | 51 | { |
| b69ab31 | | | 52 | id: 'action 1', |
| b69ab31 | | | 53 | label: 'Action 1', |
| b69ab31 | | | 54 | }, |
| b69ab31 | | | 55 | { |
| b69ab31 | | | 56 | id: 'action 2', |
| b69ab31 | | | 57 | label: 'Action 2', |
| b69ab31 | | | 58 | }, |
| b69ab31 | | | 59 | ]; |
| b69ab31 | | | 60 | const [activePanel, setActivePanel] = useState<'fruit' | 'vegetables'>('fruit'); |
| b69ab31 | | | 61 | const [buttonDropdownChoice, setButtonDropdownChoice] = useState(buttonDropdownOptions[0]); |
| b69ab31 | | | 62 | return ( |
| b69ab31 | | | 63 | <div {...stylex.props(styles.container)}> |
| b69ab31 | | | 64 | <h2>Component Explorer</h2> |
| b69ab31 | | | 65 | <div {...stylex.props(styles.container, layout.flexCol, layout.fullWidth)}> |
| b69ab31 | | | 66 | <GroupName>Colors</GroupName> |
| b69ab31 | | | 67 | <Row> |
| b69ab31 | | | 68 | Normal |
| b69ab31 | | | 69 | <Subtle>Subtle</Subtle> |
| b69ab31 | | | 70 | </Row> |
| b69ab31 | | | 71 | <Row> |
| b69ab31 | | | 72 | {basicBgs.map(name => ( |
| b69ab31 | | | 73 | <ColorBadge fg={colors.fg} bg={colors[name]} key={name}> |
| b69ab31 | | | 74 | {name} |
| b69ab31 | | | 75 | </ColorBadge> |
| b69ab31 | | | 76 | ))} |
| b69ab31 | | | 77 | </Row> |
| b69ab31 | | | 78 | <Row> |
| b69ab31 | | | 79 | {scmColors.map(name => ( |
| b69ab31 | | | 80 | <ColorBadge fg={colors[name]} bg={colors.bg} key={name}> |
| b69ab31 | | | 81 | <Icon icon="diff-modified" /> |
| b69ab31 | | | 82 | {name} |
| b69ab31 | | | 83 | </ColorBadge> |
| b69ab31 | | | 84 | ))} |
| b69ab31 | | | 85 | </Row> |
| b69ab31 | | | 86 | <Row> |
| b69ab31 | | | 87 | {pureColors.map(name => ( |
| b69ab31 | | | 88 | <ColorBadge fg={colors[name]} bg={colors.bg} key={name}> |
| b69ab31 | | | 89 | {name} |
| b69ab31 | | | 90 | </ColorBadge> |
| b69ab31 | | | 91 | ))} |
| b69ab31 | | | 92 | </Row> |
| b69ab31 | | | 93 | <Row> |
| b69ab31 | | | 94 | {pureColors.map(name => ( |
| b69ab31 | | | 95 | <ColorBadge fg={colors.fg} bg={colors[name]} key={name}> |
| b69ab31 | | | 96 | {name} |
| b69ab31 | | | 97 | </ColorBadge> |
| b69ab31 | | | 98 | ))} |
| b69ab31 | | | 99 | </Row> |
| b69ab31 | | | 100 | <Row> |
| b69ab31 | | | 101 | <ColorBadge fg={colors.errorFg} bg={colors.errorBg}> |
| b69ab31 | | | 102 | Error |
| b69ab31 | | | 103 | </ColorBadge> |
| b69ab31 | | | 104 | {signalColors.map(name => ( |
| b69ab31 | | | 105 | <ColorBadge fg={colors.signalFg} bg={colors[name]} key={name}> |
| b69ab31 | | | 106 | {name} |
| b69ab31 | | | 107 | </ColorBadge> |
| b69ab31 | | | 108 | ))} |
| b69ab31 | | | 109 | </Row> |
| b69ab31 | | | 110 | <Row> |
| b69ab31 | | | 111 | <span style={{border: '1px solid var(--focus-border)'}}>Focus border</span> |
| b69ab31 | | | 112 | <span style={{border: '1px solid var(--contrast-border)'}}>Contrast Border</span> |
| b69ab31 | | | 113 | <span style={{border: '1px solid var(--contrast-active-border)'}}> |
| b69ab31 | | | 114 | Contrast Active Border |
| b69ab31 | | | 115 | </span> |
| b69ab31 | | | 116 | </Row> |
| b69ab31 | | | 117 | <Row> |
| b69ab31 | | | 118 | <Icon icon="info" /> |
| b69ab31 | | | 119 | <Icon icon="pass" color="green" /> |
| b69ab31 | | | 120 | <Icon icon="warning" color="yellow" /> |
| b69ab31 | | | 121 | <Icon icon="error" color="red" /> |
| b69ab31 | | | 122 | <Icon icon="lightbulb" color="blue" /> |
| b69ab31 | | | 123 | </Row> |
| b69ab31 | | | 124 | <Row> |
| b69ab31 | | | 125 | XS: |
| b69ab31 | | | 126 | <Icon icon="rocket" size="XS" /> |
| b69ab31 | | | 127 | <span> </span> |
| b69ab31 | | | 128 | S: (default) |
| b69ab31 | | | 129 | <Icon icon="rocket" size="S" /> |
| b69ab31 | | | 130 | <span> </span> |
| b69ab31 | | | 131 | M: |
| b69ab31 | | | 132 | <Icon icon="rocket" size="M" /> |
| b69ab31 | | | 133 | <span> </span> |
| b69ab31 | | | 134 | L: |
| b69ab31 | | | 135 | <Icon icon="rocket" size="L" /> |
| b69ab31 | | | 136 | </Row> |
| b69ab31 | | | 137 | <GroupName>Components</GroupName> |
| b69ab31 | | | 138 | <Row> |
| b69ab31 | | | 139 | <Button primary>Primary</Button> |
| b69ab31 | | | 140 | <Button disabled primary> |
| b69ab31 | | | 141 | Primary |
| b69ab31 | | | 142 | </Button> |
| b69ab31 | | | 143 | <Button>Secondary</Button> |
| b69ab31 | | | 144 | <Button disabled>Secondary</Button> |
| b69ab31 | | | 145 | <Button icon>Icon</Button> |
| b69ab31 | | | 146 | <Button icon> |
| b69ab31 | | | 147 | <Icon icon="rocket" /> |
| b69ab31 | | | 148 | Icon |
| b69ab31 | | | 149 | </Button> |
| b69ab31 | | | 150 | <Button icon> |
| b69ab31 | | | 151 | <Icon icon="rocket" /> |
| b69ab31 | | | 152 | </Button> |
| b69ab31 | | | 153 | <Button icon disabled> |
| b69ab31 | | | 154 | <Icon icon="rocket" /> Icon |
| b69ab31 | | | 155 | </Button> |
| b69ab31 | | | 156 | <Button> |
| b69ab31 | | | 157 | <Icon icon="rocket" /> Secondary With Icon |
| b69ab31 | | | 158 | </Button> |
| b69ab31 | | | 159 | </Row> |
| b69ab31 | | | 160 | <Row> |
| b69ab31 | | | 161 | <Dropdown |
| b69ab31 | | | 162 | options={['Dropdown', 'Option']} |
| b69ab31 | | | 163 | onChange={e => console.log(e.currentTarget.value)} |
| b69ab31 | | | 164 | /> |
| b69ab31 | | | 165 | <Dropdown |
| b69ab31 | | | 166 | disabled |
| b69ab31 | | | 167 | options={[ |
| b69ab31 | | | 168 | {value: 'none', name: 'Disabled Option', disabled: true}, |
| b69ab31 | | | 169 | {value: 'drop', name: 'Dropdown'}, |
| b69ab31 | | | 170 | {value: 'opt', name: 'Option'}, |
| b69ab31 | | | 171 | ]} |
| b69ab31 | | | 172 | onChange={e => console.log(e.currentTarget.value)} |
| b69ab31 | | | 173 | /> |
| b69ab31 | | | 174 | <Dropdown |
| b69ab31 | | | 175 | value={dropdownChoice} |
| b69ab31 | | | 176 | onChange={e => setDropdownChoice(e.currentTarget.value)} |
| b69ab31 | | | 177 | options={['A', 'B', 'C']} |
| b69ab31 | | | 178 | /> |
| b69ab31 | | | 179 | </Row> |
| b69ab31 | | | 180 | <Row> |
| b69ab31 | | | 181 | <ButtonDropdown |
| b69ab31 | | | 182 | icon={<Icon icon="rocket" />} |
| b69ab31 | | | 183 | options={buttonDropdownOptions} |
| b69ab31 | | | 184 | selected={buttonDropdownChoice} |
| b69ab31 | | | 185 | onClick={selected => console.log('click!', selected)} |
| b69ab31 | | | 186 | onChangeSelected={setButtonDropdownChoice} |
| b69ab31 | | | 187 | /> |
| b69ab31 | | | 188 | <ButtonDropdown |
| b69ab31 | | | 189 | options={buttonDropdownOptions} |
| b69ab31 | | | 190 | buttonDisabled |
| b69ab31 | | | 191 | selected={buttonDropdownChoice} |
| b69ab31 | | | 192 | onClick={selected => console.log('click!', selected)} |
| b69ab31 | | | 193 | onChangeSelected={setButtonDropdownChoice} |
| b69ab31 | | | 194 | /> |
| b69ab31 | | | 195 | <ButtonDropdown |
| b69ab31 | | | 196 | options={buttonDropdownOptions} |
| b69ab31 | | | 197 | pickerDisabled |
| b69ab31 | | | 198 | selected={buttonDropdownChoice} |
| b69ab31 | | | 199 | onClick={selected => console.log('click!', selected)} |
| b69ab31 | | | 200 | onChangeSelected={setButtonDropdownChoice} |
| b69ab31 | | | 201 | /> |
| b69ab31 | | | 202 | <ButtonDropdown |
| b69ab31 | | | 203 | icon={<Icon icon="rocket" />} |
| b69ab31 | | | 204 | kind="icon" |
| b69ab31 | | | 205 | options={buttonDropdownOptions} |
| b69ab31 | | | 206 | selected={buttonDropdownChoice} |
| b69ab31 | | | 207 | onClick={selected => console.log('click!', selected)} |
| b69ab31 | | | 208 | onChangeSelected={setButtonDropdownChoice} |
| b69ab31 | | | 209 | /> |
| b69ab31 | | | 210 | <ButtonDropdown |
| b69ab31 | | | 211 | kind="icon" |
| b69ab31 | | | 212 | options={buttonDropdownOptions} |
| b69ab31 | | | 213 | buttonDisabled |
| b69ab31 | | | 214 | selected={buttonDropdownChoice} |
| b69ab31 | | | 215 | onClick={selected => console.log('click!', selected)} |
| b69ab31 | | | 216 | onChangeSelected={setButtonDropdownChoice} |
| b69ab31 | | | 217 | /> |
| b69ab31 | | | 218 | <ButtonDropdown |
| b69ab31 | | | 219 | kind="icon" |
| b69ab31 | | | 220 | options={buttonDropdownOptions} |
| b69ab31 | | | 221 | pickerDisabled |
| b69ab31 | | | 222 | selected={buttonDropdownChoice} |
| b69ab31 | | | 223 | onClick={selected => console.log('click!', selected)} |
| b69ab31 | | | 224 | onChangeSelected={setButtonDropdownChoice} |
| b69ab31 | | | 225 | /> |
| b69ab31 | | | 226 | </Row> |
| b69ab31 | | | 227 | <Row> |
| b69ab31 | | | 228 | <ButtonGroup> |
| b69ab31 | | | 229 | <Button>A</Button> |
| b69ab31 | | | 230 | <Tooltip title="Wrapping in a tooltip doesn't affect the group styling"> |
| b69ab31 | | | 231 | <Button>B</Button> |
| b69ab31 | | | 232 | </Tooltip> |
| b69ab31 | | | 233 | <Button> |
| b69ab31 | | | 234 | <Icon icon="close" /> |
| b69ab31 | | | 235 | </Button> |
| b69ab31 | | | 236 | </ButtonGroup> |
| b69ab31 | | | 237 | <ButtonGroup |
| b69ab31 | | | 238 | icon /* Be sure to set icon=True on the group if the buttons are icon=True */ |
| b69ab31 | | | 239 | > |
| b69ab31 | | | 240 | <Button icon style={{paddingInline: '5px'}}> |
| b69ab31 | | | 241 | Action A |
| b69ab31 | | | 242 | </Button> |
| b69ab31 | | | 243 | <Button icon style={{paddingInline: '5px'}}> |
| b69ab31 | | | 244 | Action B |
| b69ab31 | | | 245 | </Button> |
| b69ab31 | | | 246 | <Button icon> |
| b69ab31 | | | 247 | <Icon icon="close" /> |
| b69ab31 | | | 248 | </Button> |
| b69ab31 | | | 249 | </ButtonGroup> |
| b69ab31 | | | 250 | <ButtonGroup> |
| b69ab31 | | | 251 | <Button>A</Button> |
| b69ab31 | | | 252 | <Button disabled>B</Button> |
| b69ab31 | | | 253 | <Button>C</Button> |
| b69ab31 | | | 254 | <Button primary>D</Button> |
| b69ab31 | | | 255 | <Button> |
| b69ab31 | | | 256 | <Icon icon="close" /> |
| b69ab31 | | | 257 | </Button> |
| b69ab31 | | | 258 | </ButtonGroup> |
| b69ab31 | | | 259 | </Row> |
| b69ab31 | | | 260 | <Row> |
| b69ab31 | | | 261 | <Checkbox checked={checkbox1} onChange={setCheckbox1}> |
| b69ab31 | | | 262 | Checkbox |
| b69ab31 | | | 263 | </Checkbox> |
| b69ab31 | | | 264 | <Checkbox checked={checkbox2} onChange={setCheckbox2}> |
| b69ab31 | | | 265 | Checked |
| b69ab31 | | | 266 | </Checkbox> |
| b69ab31 | | | 267 | <Checkbox checked={false} indeterminate onChange={console.log}> |
| b69ab31 | | | 268 | Indeterminate |
| b69ab31 | | | 269 | </Checkbox> |
| b69ab31 | | | 270 | <Checkbox checked disabled onChange={setCheckbox1}> |
| b69ab31 | | | 271 | Disabled |
| b69ab31 | | | 272 | </Checkbox> |
| b69ab31 | | | 273 | <RadioGroup |
| b69ab31 | | | 274 | choices={[ |
| b69ab31 | | | 275 | {title: 'Radio', value: 'radio'}, |
| b69ab31 | | | 276 | {title: 'Another', value: 'another'}, |
| b69ab31 | | | 277 | ]} |
| b69ab31 | | | 278 | current={radioChoice} |
| b69ab31 | | | 279 | onChange={setRadioChoice} |
| b69ab31 | | | 280 | /> |
| b69ab31 | | | 281 | </Row> |
| b69ab31 | | | 282 | <Row> |
| b69ab31 | | | 283 | Kbd: |
| b69ab31 | | | 284 | <Kbd keycode={KeyCode.A} modifiers={[Modifier.CMD]} /> |
| b69ab31 | | | 285 | </Row> |
| b69ab31 | | | 286 | <Row> |
| b69ab31 | | | 287 | <Badge>Badge</Badge> |
| b69ab31 | | | 288 | <Badge>0</Badge> |
| b69ab31 | | | 289 | <Tag>Tag</Tag> |
| b69ab31 | | | 290 | <Tag>0</Tag> |
| b69ab31 | | | 291 | {/* <Link href={'#'}>Link</Link> */} |
| b69ab31 | | | 292 | <Icon icon="loading" /> |
| b69ab31 | | | 293 | Loading |
| b69ab31 | | | 294 | </Row> |
| b69ab31 | | | 295 | <Divider /> |
| b69ab31 | | | 296 | <Row> |
| b69ab31 | | | 297 | <TextArea placeholder="placeholder" onChange={e => console.log(e.currentTarget.value)}> |
| b69ab31 | | | 298 | Text area |
| b69ab31 | | | 299 | </TextArea> |
| b69ab31 | | | 300 | <TextField placeholder="placeholder" onChange={e => console.log(e.currentTarget.value)}> |
| b69ab31 | | | 301 | Text Field |
| b69ab31 | | | 302 | </TextField> |
| b69ab31 | | | 303 | <Tooltip trigger="manual" shouldShow={true} title="Tooltip" placement="bottom"> |
| b69ab31 | | | 304 | Thing |
| b69ab31 | | | 305 | </Tooltip> |
| b69ab31 | | | 306 | </Row> |
| b69ab31 | | | 307 | <Row> |
| b69ab31 | | | 308 | <HorizontallyGrowingTextField |
| b69ab31 | | | 309 | placeholder="grows as you type" |
| b69ab31 | | | 310 | onInput={e => console.log(e.currentTarget.value)} |
| b69ab31 | | | 311 | /> |
| b69ab31 | | | 312 | </Row> |
| b69ab31 | | | 313 | <Row> |
| b69ab31 | | | 314 | <span>Typeahead:</span> |
| b69ab31 | | | 315 | <ExampleTypeahead /> |
| b69ab31 | | | 316 | </Row> |
| b69ab31 | | | 317 | |
| b69ab31 | | | 318 | <Row> |
| b69ab31 | | | 319 | <Banner>Banner</Banner> |
| b69ab31 | | | 320 | <Banner kind={BannerKind.warning}>Warning Banner</Banner> |
| b69ab31 | | | 321 | <Banner kind={BannerKind.error}>Error Banner</Banner> |
| b69ab31 | | | 322 | <Banner icon={<Icon icon="info" />}>Icon Banner</Banner> |
| b69ab31 | | | 323 | </Row> |
| b69ab31 | | | 324 | <Row> |
| b69ab31 | | | 325 | <ErrorNotice |
| b69ab31 | | | 326 | title="Error Notice" |
| b69ab31 | | | 327 | description="description" |
| b69ab31 | | | 328 | details="details / stack trace" |
| b69ab31 | | | 329 | /> |
| b69ab31 | | | 330 | </Row> |
| b69ab31 | | | 331 | <Row> |
| b69ab31 | | | 332 | <Panels |
| b69ab31 | | | 333 | active={activePanel} |
| b69ab31 | | | 334 | panels={{ |
| b69ab31 | | | 335 | fruit: {label: 'Fruit', render: () => <div>Apple</div>}, |
| b69ab31 | | | 336 | vegetables: {label: 'Vegetables', render: () => <div>Broccoli</div>}, |
| b69ab31 | | | 337 | }} |
| b69ab31 | | | 338 | onSelect={setActivePanel} |
| b69ab31 | | | 339 | /> |
| b69ab31 | | | 340 | </Row> |
| b69ab31 | | | 341 | <GroupName>Spacing</GroupName> |
| b69ab31 | | | 342 | <Row> |
| b69ab31 | | | 343 | {paddings.map(size => ( |
| b69ab31 | | | 344 | <ColorBadge style={styles.padding(size)} key={size}> |
| b69ab31 | | | 345 | {size} |
| b69ab31 | | | 346 | </ColorBadge> |
| b69ab31 | | | 347 | ))} |
| b69ab31 | | | 348 | </Row> |
| b69ab31 | | | 349 | <Row> |
| b69ab31 | | | 350 | <div {...stylex.props(layout.flexCol)} style={{alignItems: 'flex-start'}}> |
| b69ab31 | | | 351 | {paddings.map(size => ( |
| b69ab31 | | | 352 | <div {...stylex.props(layout.flexRow)} style={{gap: spacing[size]}} key={size}> |
| b69ab31 | | | 353 | <ColorBadge>A</ColorBadge> |
| b69ab31 | | | 354 | <ColorBadge>B</ColorBadge> |
| b69ab31 | | | 355 | <ColorBadge>{size}</ColorBadge> |
| b69ab31 | | | 356 | </div> |
| b69ab31 | | | 357 | ))} |
| b69ab31 | | | 358 | </div> |
| b69ab31 | | | 359 | </Row> |
| b69ab31 | | | 360 | <GroupName>Font</GroupName> |
| b69ab31 | | | 361 | <Row> |
| b69ab31 | | | 362 | {fontSizes.map(size => ( |
| b69ab31 | | | 363 | <ColorBadge style={styles.font(size)} bg={colors.hoverDarken} key={size}> |
| b69ab31 | | | 364 | {size} |
| b69ab31 | | | 365 | </ColorBadge> |
| b69ab31 | | | 366 | ))} |
| b69ab31 | | | 367 | </Row> |
| b69ab31 | | | 368 | </div> |
| b69ab31 | | | 369 | </div> |
| b69ab31 | | | 370 | ); |
| b69ab31 | | | 371 | } |
| b69ab31 | | | 372 | |
| b69ab31 | | | 373 | const styles = stylex.create({ |
| b69ab31 | | | 374 | container: { |
| b69ab31 | | | 375 | padding: spacing.pad, |
| b69ab31 | | | 376 | overflow: 'auto', |
| b69ab31 | | | 377 | }, |
| b69ab31 | | | 378 | badge: (fg, bg) => ({ |
| b69ab31 | | | 379 | backgroundColor: bg, |
| b69ab31 | | | 380 | color: fg, |
| b69ab31 | | | 381 | fontFamily: 'monospace', |
| b69ab31 | | | 382 | paddingBlock: spacing.half, |
| b69ab31 | | | 383 | paddingInline: spacing.pad, |
| b69ab31 | | | 384 | borderRadius: radius.round, |
| b69ab31 | | | 385 | }), |
| b69ab31 | | | 386 | groupName: { |
| b69ab31 | | | 387 | fontSize: font.bigger, |
| b69ab31 | | | 388 | width: '100%', |
| b69ab31 | | | 389 | paddingTop: spacing.double, |
| b69ab31 | | | 390 | fontWeight: 'bold', |
| b69ab31 | | | 391 | }, |
| b69ab31 | | | 392 | padding: (pad: (typeof paddings)[number]) => ({ |
| b69ab31 | | | 393 | padding: spacing[pad], |
| b69ab31 | | | 394 | }), |
| b69ab31 | | | 395 | font: (size: (typeof fontSizes)[number]) => ({ |
| b69ab31 | | | 396 | fontSize: font[size], |
| b69ab31 | | | 397 | }), |
| b69ab31 | | | 398 | }); |
| b69ab31 | | | 399 | |
| b69ab31 | | | 400 | function ColorBadge({ |
| b69ab31 | | | 401 | children, |
| b69ab31 | | | 402 | bg, |
| b69ab31 | | | 403 | fg, |
| b69ab31 | | | 404 | style, |
| b69ab31 | | | 405 | }: { |
| b69ab31 | | | 406 | children: ReactNode; |
| b69ab31 | | | 407 | bg?: StyleXVar<string>; |
| b69ab31 | | | 408 | fg?: StyleXVar<string>; |
| b69ab31 | | | 409 | style?: stylex.StyleXStyles; |
| b69ab31 | | | 410 | }) { |
| b69ab31 | | | 411 | return ( |
| b69ab31 | | | 412 | <div {...stylex.props(layout.flexRow, styles.badge(fg, bg ?? colors.hoverDarken), style)}> |
| b69ab31 | | | 413 | {children} |
| b69ab31 | | | 414 | </div> |
| b69ab31 | | | 415 | ); |
| b69ab31 | | | 416 | } |
| b69ab31 | | | 417 | |
| b69ab31 | | | 418 | function Row({children, style}: {children: ReactNode; style?: stylex.StyleXStyles}) { |
| b69ab31 | | | 419 | return <div {...stylex.props(layout.flexRow, layout.fullWidth, style)}>{children}</div>; |
| b69ab31 | | | 420 | } |
| b69ab31 | | | 421 | |
| b69ab31 | | | 422 | function GroupName({children}: {children: ReactNode}) { |
| b69ab31 | | | 423 | return <div {...stylex.props(styles.groupName)}>{children}</div>; |
| b69ab31 | | | 424 | } |
| b69ab31 | | | 425 | |
| b69ab31 | | | 426 | function ExampleTypeahead() { |
| b69ab31 | | | 427 | const [value, setValue] = useState(''); |
| b69ab31 | | | 428 | |
| b69ab31 | | | 429 | const possibleValues = [ |
| b69ab31 | | | 430 | 'apple', |
| b69ab31 | | | 431 | 'banana', |
| b69ab31 | | | 432 | 'cherry', |
| b69ab31 | | | 433 | 'date', |
| b69ab31 | | | 434 | 'elderberry', |
| b69ab31 | | | 435 | 'fig', |
| b69ab31 | | | 436 | 'grape', |
| b69ab31 | | | 437 | 'honeydew', |
| b69ab31 | | | 438 | 'jackfruit', |
| b69ab31 | | | 439 | 'kiwi', |
| b69ab31 | | | 440 | ]; |
| b69ab31 | | | 441 | const fetchTokens = async (searchTerm: string) => { |
| b69ab31 | | | 442 | await new Promise(resolve => setTimeout(resolve, 500)); |
| b69ab31 | | | 443 | return { |
| b69ab31 | | | 444 | values: possibleValues |
| b69ab31 | | | 445 | .filter(v => v.includes(searchTerm)) |
| b69ab31 | | | 446 | .map(value => ({ |
| b69ab31 | | | 447 | label: value, |
| b69ab31 | | | 448 | value, |
| b69ab31 | | | 449 | })), |
| b69ab31 | | | 450 | fetchStartTimestamp: Date.now(), |
| b69ab31 | | | 451 | }; |
| b69ab31 | | | 452 | }; |
| b69ab31 | | | 453 | return ( |
| b69ab31 | | | 454 | <Typeahead |
| b69ab31 | | | 455 | tokenString={value} |
| b69ab31 | | | 456 | setTokenString={setValue} |
| b69ab31 | | | 457 | fetchTokens={fetchTokens} |
| b69ab31 | | | 458 | autoFocus={false} |
| b69ab31 | | | 459 | maxTokens={3} |
| b69ab31 | | | 460 | /> |
| b69ab31 | | | 461 | ); |
| b69ab31 | | | 462 | } |