|
1 | | -import { Button, Heading } from '@cfpb/design-system-react' |
| 1 | +import { useState } from 'react' |
| 2 | +import { |
| 3 | + Alert, |
| 4 | + Button, |
| 5 | + Checkbox, |
| 6 | + Divider, |
| 7 | + Expandable, |
| 8 | + FooterCfGov, |
| 9 | + Header, |
| 10 | + Heading, |
| 11 | + Hero, |
| 12 | + Label, |
| 13 | + Layout, |
| 14 | + Link, |
| 15 | + List, |
| 16 | + Paragraph, |
| 17 | + SecondaryNav, |
| 18 | + SkipNav, |
| 19 | + Tab, |
| 20 | + TabList, |
| 21 | + TabPanel, |
| 22 | + TextInput, |
| 23 | + WellContent, |
| 24 | +} from '@cfpb/design-system-react' |
2 | 25 | import './App.css' |
3 | 26 |
|
| 27 | +const headerLinks = [ |
| 28 | + <Link key='components' to='#components' label='Components' />, |
| 29 | + <Link key='patterns' to='#patterns' label='Patterns' />, |
| 30 | + <Link key='forms' to='#forms' label='Forms' />, |
| 31 | + <Link |
| 32 | + key='docs' |
| 33 | + to='https://cfpb.github.io/design-system-react/' |
| 34 | + label='Storybook' |
| 35 | + />, |
| 36 | +] |
| 37 | + |
| 38 | +const sidebarNav = [ |
| 39 | + { |
| 40 | + label: 'On this page', |
| 41 | + children: [ |
| 42 | + { to: '#components', label: 'Components', isActive: true }, |
| 43 | + { to: '#patterns', label: 'Patterns' }, |
| 44 | + { to: '#forms', label: 'Forms' }, |
| 45 | + { to: '#about', label: 'About this demo' }, |
| 46 | + ], |
| 47 | + }, |
| 48 | +] |
| 49 | + |
4 | 50 | function App() { |
| 51 | + const [activeTab, setActiveTab] = useState('overview') |
| 52 | + const [newsletterEmail, setNewsletterEmail] = useState('') |
| 53 | + const [wantsUpdates, setWantsUpdates] = useState(false) |
| 54 | + |
5 | 55 | return ( |
6 | | - <main className='demo'> |
7 | | - <Heading type='slug'>Design System React</Heading> |
8 | | - <p className='demo__intro'> |
9 | | - Local demo for <code>@cfpb/design-system-react</code> components. |
10 | | - </p> |
11 | | - |
12 | | - <section className='demo__section'> |
13 | | - <Heading type='2'>Button</Heading> |
14 | | - <div className='demo__row'> |
15 | | - <Button label='Primary' onClick={() => {}} /> |
16 | | - <Button |
17 | | - label='Secondary' |
18 | | - appearance='secondary' |
19 | | - onClick={() => {}} |
20 | | - /> |
21 | | - </div> |
22 | | - </section> |
23 | | - |
24 | | - <section className='demo__section'> |
25 | | - <Heading type='2'>Heading</Heading> |
26 | | - <Heading type='3'>Level 3 heading</Heading> |
27 | | - </section> |
28 | | - </main> |
| 56 | + <> |
| 57 | + <SkipNav href='#main' /> |
| 58 | + <Header |
| 59 | + href='https://www.consumerfinance.gov' |
| 60 | + links={headerLinks} |
| 61 | + /> |
| 62 | + |
| 63 | + <Layout.Main id='main' layout='2-1'> |
| 64 | + <Hero |
| 65 | + heading='Design System React in action' |
| 66 | + subheading='A standalone Vite app that loads @cfpb/design-system-react the same way a new consumerfinance.gov experience would — Pattern A with one stylesheet.' |
| 67 | + backgroundColor='#d4e7e6' |
| 68 | + image='https://cfpb.github.io/design-system/images/uploads/design_system_illustration_hero_example.png' |
| 69 | + imageAltText='Abstract illustration of the CFPB Design System' |
| 70 | + /> |
| 71 | + |
| 72 | + <Layout.Wrapper> |
| 73 | + <Layout.Content> |
| 74 | + <Alert |
| 75 | + status='info' |
| 76 | + message='This page is a consumer demo, not an official consumerfinance.gov page.' |
| 77 | + > |
| 78 | + It exercises published DSR components together — Header, Hero, |
| 79 | + Layout, Tabs, forms, Expandable, Well, and Footer — outside |
| 80 | + Storybook. |
| 81 | + </Alert> |
| 82 | + |
| 83 | + <section id='components' className='page-section'> |
| 84 | + <Heading type='2'>Start with familiar building blocks</Heading> |
| 85 | + <Paragraph> |
| 86 | + Buttons, headings, lists, and alerts ship with Design System |
| 87 | + styles via <code>@cfpb/design-system-react/index.css</code>. No |
| 88 | + separate Design System CSS import is required for Pattern A. |
| 89 | + </Paragraph> |
| 90 | + |
| 91 | + <div className='demo-row'> |
| 92 | + <Button label='Primary action' onClick={() => {}} /> |
| 93 | + <Button |
| 94 | + label='Secondary' |
| 95 | + appearance='secondary' |
| 96 | + onClick={() => {}} |
| 97 | + /> |
| 98 | + <Button label='Text link style' isLink onClick={() => {}} /> |
| 99 | + </div> |
| 100 | + |
| 101 | + <List> |
| 102 | + <li>Greenfield React apps can start with Pattern A alone.</li> |
| 103 | + <li> |
| 104 | + Existing CFPB apps that already load full Design System CSS |
| 105 | + should use Pattern B and <code>dsr.css</code> instead. |
| 106 | + </li> |
| 107 | + <li> |
| 108 | + Storybook in DSR compiles the same Pattern A source stack via{' '} |
| 109 | + <code>entry-styles.ts</code>. |
| 110 | + </li> |
| 111 | + </List> |
| 112 | + </section> |
| 113 | + |
| 114 | + <Divider /> |
| 115 | + |
| 116 | + <section id='patterns' className='page-section'> |
| 117 | + <Heading type='2'>Compose page patterns</Heading> |
| 118 | + <Paragraph> |
| 119 | + Tabs, expandables, and wells help organize denser content the |
| 120 | + way browse and learn pages do on consumerfinance.gov. |
| 121 | + </Paragraph> |
| 122 | + |
| 123 | + <Heading type='3'>Tabs</Heading> |
| 124 | + <TabList> |
| 125 | + <Tab |
| 126 | + id='overview' |
| 127 | + value='overview' |
| 128 | + label='Overview' |
| 129 | + isActive={activeTab === 'overview'} |
| 130 | + onClick={(event) => setActiveTab(event.currentTarget.value)} |
| 131 | + /> |
| 132 | + <Tab |
| 133 | + id='layout' |
| 134 | + value='layout' |
| 135 | + label='Layout' |
| 136 | + isActive={activeTab === 'layout'} |
| 137 | + onClick={(event) => setActiveTab(event.currentTarget.value)} |
| 138 | + /> |
| 139 | + <Tab |
| 140 | + id='footer' |
| 141 | + value='footer' |
| 142 | + label='Footer' |
| 143 | + isActive={activeTab === 'footer'} |
| 144 | + onClick={(event) => setActiveTab(event.currentTarget.value)} |
| 145 | + /> |
| 146 | + </TabList> |
| 147 | + <TabPanel id={activeTab}> |
| 148 | + {activeTab === 'overview' && ( |
| 149 | + <Paragraph> |
| 150 | + Inactive tabs use DSR link chrome (blue, dotted underline). |
| 151 | + The active tab is a gray chip on the baseline — the same |
| 152 | + treatment as Storybook. |
| 153 | + </Paragraph> |
| 154 | + )} |
| 155 | + {activeTab === 'layout' && ( |
| 156 | + <Paragraph> |
| 157 | + This page uses <code>Layout.Main</code>,{' '} |
| 158 | + <code>Layout.Wrapper</code>, <code>Layout.Content</code>, |
| 159 | + and <code>Layout.Sidebar</code> with a 2-1 column split. |
| 160 | + </Paragraph> |
| 161 | + )} |
| 162 | + {activeTab === 'footer' && ( |
| 163 | + <Paragraph> |
| 164 | + The footer below is <code>FooterCfGov</code>, the packaged |
| 165 | + consumerfinance.gov footer composition. |
| 166 | + </Paragraph> |
| 167 | + )} |
| 168 | + </TabPanel> |
| 169 | + |
| 170 | + <Heading type='3'>Expandable</Heading> |
| 171 | + <Expandable header='How is CSS loaded in this demo?'> |
| 172 | + <Paragraph> |
| 173 | + <code>src/main.tsx</code> imports{' '} |
| 174 | + <code>@cfpb/design-system-react/index.css</code> (Pattern A). |
| 175 | + That single file includes fonts, curated Design System |
| 176 | + modules, and DSR-authored styles such as Tabs. |
| 177 | + </Paragraph> |
| 178 | + </Expandable> |
| 179 | + |
| 180 | + <WellContent |
| 181 | + heading='Need the full Design System?' |
| 182 | + text='If your app already compiles @cfpb/cfpb-design-system CSS, switch to Pattern B: keep that stylesheet and import @cfpb/design-system-react/dsr.css for Tabs and other React-only rules.' |
| 183 | + links={[ |
| 184 | + <Link |
| 185 | + key='readme' |
| 186 | + to='https://github.com/cfpb/design-system-react#pattern-b-full-ds-css--thin-dsrcss-existing-cfpb-apps' |
| 187 | + label='Read Pattern B docs' |
| 188 | + />, |
| 189 | + ]} |
| 190 | + /> |
| 191 | + </section> |
| 192 | + |
| 193 | + <Divider /> |
| 194 | + |
| 195 | + <section id='forms' className='page-section'> |
| 196 | + <Heading type='2'>Collect a little input</Heading> |
| 197 | + <Paragraph> |
| 198 | + Form controls use the same Design System classes as production |
| 199 | + CFPB forms. |
| 200 | + </Paragraph> |
| 201 | + |
| 202 | + <div className='form-stack'> |
| 203 | + <div className='m-form-field'> |
| 204 | + <Label htmlFor='newsletter-email'>Email address</Label> |
| 205 | + <TextInput |
| 206 | + id='newsletter-email' |
| 207 | + name='newsletter-email' |
| 208 | + type='email' |
| 209 | + value={newsletterEmail} |
| 210 | + onChange={(event) => |
| 211 | + setNewsletterEmail(event.currentTarget.value) |
| 212 | + } |
| 213 | + placeholder='you@example.com' |
| 214 | + /> |
| 215 | + </div> |
| 216 | + <Checkbox |
| 217 | + id='newsletter-opt-in' |
| 218 | + label='Send me updates about Design System React' |
| 219 | + checked={wantsUpdates} |
| 220 | + onChange={(event) => |
| 221 | + setWantsUpdates(event.currentTarget.checked) |
| 222 | + } |
| 223 | + /> |
| 224 | + <Button label='Submit (demo only)' onClick={() => {}} /> |
| 225 | + </div> |
| 226 | + </section> |
| 227 | + |
| 228 | + <Divider /> |
| 229 | + |
| 230 | + <section id='about' className='page-section'> |
| 231 | + <Heading type='2'>About this demo</Heading> |
| 232 | + <Paragraph> |
| 233 | + <strong>dsr-test</strong> is a kitchen-sink Vite consumer for{' '} |
| 234 | + <code>@cfpb/design-system-react</code>. It exists to prove that |
| 235 | + published components work together in a standalone app — not |
| 236 | + only inside Storybook. |
| 237 | + </Paragraph> |
| 238 | + <div className='demo-row'> |
| 239 | + <Link |
| 240 | + to='https://github.com/cfpb/design-system-react' |
| 241 | + label='design-system-react on GitHub' |
| 242 | + /> |
| 243 | + <Link |
| 244 | + to='https://cfpb.github.io/design-system-react/' |
| 245 | + label='DSR Storybook' |
| 246 | + /> |
| 247 | + <Link |
| 248 | + to='https://cfpb.github.io/design-system/' |
| 249 | + label='Design System docs' |
| 250 | + /> |
| 251 | + </div> |
| 252 | + </section> |
| 253 | + </Layout.Content> |
| 254 | + |
| 255 | + <Layout.Sidebar> |
| 256 | + <SecondaryNav items={sidebarNav} ariaLabel='On this page' /> |
| 257 | + </Layout.Sidebar> |
| 258 | + </Layout.Wrapper> |
| 259 | + </Layout.Main> |
| 260 | + |
| 261 | + <FooterCfGov /> |
| 262 | + </> |
29 | 263 | ) |
30 | 264 | } |
31 | 265 |
|
|
0 commit comments