@jamesodwyer/gds-figma-vite 2.0.3 → 2.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
# Ticketmaster Global Design System (GDS) - AI Guidelines
|
|
2
|
+
|
|
3
|
+
> **FOR AI AGENTS**: This is a self-contained guide for code generation. All information is in this single file.
|
|
4
|
+
|
|
5
|
+
## Package Information
|
|
6
|
+
|
|
7
|
+
- **Package**: `@jamesodwyer/gds-figma-vite`
|
|
8
|
+
- **Framework**: React 18+ with styled-components
|
|
9
|
+
- **Themes**: TM (Ticketmaster/blue), LN (Live Nation/red)
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## REQUIRED: GdsProvider Wrapper
|
|
14
|
+
|
|
15
|
+
Every application MUST wrap components with `GdsProvider`:
|
|
16
|
+
|
|
17
|
+
```tsx
|
|
18
|
+
import { GdsProvider, Button } from '@jamesodwyer/gds-figma-vite';
|
|
19
|
+
|
|
20
|
+
function App() {
|
|
21
|
+
return (
|
|
22
|
+
<GdsProvider theme="TM">
|
|
23
|
+
<Button colorVariant="primary">Click Me</Button>
|
|
24
|
+
</GdsProvider>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
| Prop | Type | Default | Description |
|
|
30
|
+
|------|------|---------|-------------|
|
|
31
|
+
| theme | 'TM' \| 'LN' | 'TM' | Brand theme |
|
|
32
|
+
| includeGlobalStyles | boolean | true | Include global CSS |
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## CRITICAL: Compound Component Pattern
|
|
37
|
+
|
|
38
|
+
Many GDS components use **dot notation** for sub-components. These are NOT separate imports.
|
|
39
|
+
|
|
40
|
+
### Correct Usage
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
// CORRECT - Use dot notation
|
|
44
|
+
<Modal>
|
|
45
|
+
<Modal.Header>
|
|
46
|
+
<Modal.Title>Title</Modal.Title>
|
|
47
|
+
<Modal.CloseButton label="Close" />
|
|
48
|
+
</Modal.Header>
|
|
49
|
+
<Modal.Content>
|
|
50
|
+
<Modal.Description>Content here</Modal.Description>
|
|
51
|
+
</Modal.Content>
|
|
52
|
+
<Modal.Actions>
|
|
53
|
+
<Button colorVariant="secondary">Cancel</Button>
|
|
54
|
+
<Button colorVariant="primary">Confirm</Button>
|
|
55
|
+
</Modal.Actions>
|
|
56
|
+
</Modal>
|
|
57
|
+
|
|
58
|
+
<Card>
|
|
59
|
+
<Card.Title>Card Title</Card.Title>
|
|
60
|
+
<Card.Body>Card content</Card.Body>
|
|
61
|
+
</Card>
|
|
62
|
+
|
|
63
|
+
<InputField id="email">
|
|
64
|
+
<InputField.Label>Email</InputField.Label>
|
|
65
|
+
<InputField.Row marginTop="club">
|
|
66
|
+
<InputField.Input type="email" />
|
|
67
|
+
</InputField.Row>
|
|
68
|
+
</InputField>
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### Components with Sub-components
|
|
72
|
+
|
|
73
|
+
| Component | Sub-components (use dot notation) |
|
|
74
|
+
|-----------|-----------------------------------|
|
|
75
|
+
| `Modal` | `.Header`, `.Title`, `.Content`, `.Description`, `.Image`, `.CloseButton`, `.Actions` |
|
|
76
|
+
| `Card` | `.Title`, `.Body` |
|
|
77
|
+
| `InputField` | `.Label`, `.Row`, `.Input`, `.Textarea`, `.Select`, `.Checkbox`, `.Radio`, `.StartIcon`, `.EndIcon`, `.Validation` |
|
|
78
|
+
| `Accordion` | `.Item`, `.Toggle`, `.Content` |
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## CRITICAL: Components That DO NOT Exist
|
|
83
|
+
|
|
84
|
+
> **WARNING**: These components are NOT in GDS. Do NOT use them.
|
|
85
|
+
|
|
86
|
+
| DO NOT USE | Use Instead |
|
|
87
|
+
|------------|-------------|
|
|
88
|
+
| `ButtonGroup` | `<div style={{display:'flex',gap:'8px'}}>` or styled div |
|
|
89
|
+
| `CardContent` | Put content directly in `Card.Body` |
|
|
90
|
+
| `CardHeader` | Use `Card.Title` |
|
|
91
|
+
| `CardActions` | Put buttons in `Card.Body` |
|
|
92
|
+
| `ModalDescription` | Use `Modal.Description` (dot notation) |
|
|
93
|
+
| `ModalHeader` | Use `Modal.Header` (dot notation) |
|
|
94
|
+
| `ModalBody` | Use `Modal.Content` (dot notation) |
|
|
95
|
+
| `ModalFooter` | Use `Modal.Actions` (dot notation) |
|
|
96
|
+
| `FormControl` | Use `InputField` |
|
|
97
|
+
| `FormLabel` | Use `InputField.Label` |
|
|
98
|
+
| `Grid` | Use CSS Grid or styled div |
|
|
99
|
+
| `Box` | Use styled div |
|
|
100
|
+
| `Container` | Use styled div |
|
|
101
|
+
| `Typography` | Use `TextStyle` |
|
|
102
|
+
| `Divider` | Use styled hr or div |
|
|
103
|
+
| `Snackbar` | Use `Toast` |
|
|
104
|
+
| `Dialog` | Use `Modal` |
|
|
105
|
+
| `Drawer` | Use `SidePanel` |
|
|
106
|
+
|
|
107
|
+
### Button Row Example (Instead of ButtonGroup)
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
// For horizontal button layouts:
|
|
111
|
+
<div style={{ display: 'flex', gap: '8px' }}>
|
|
112
|
+
<Button colorVariant="secondary">Cancel</Button>
|
|
113
|
+
<Button colorVariant="primary">Confirm</Button>
|
|
114
|
+
</div>
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Available Components
|
|
120
|
+
|
|
121
|
+
### Layout
|
|
122
|
+
- `Card` - Container with `.Title`, `.Body`
|
|
123
|
+
- `Modal` - Dialog with `.Header`, `.Title`, `.Content`, `.Description`, `.CloseButton`, `.Actions`
|
|
124
|
+
- `SidePanel` - Slide-in panel
|
|
125
|
+
- `Accordion` - Collapsible sections
|
|
126
|
+
- `Header` - Page header
|
|
127
|
+
- `Footer` - Page footer
|
|
128
|
+
|
|
129
|
+
### Buttons
|
|
130
|
+
- `Button` - Primary button (colorVariant: 'primary' | 'secondary' | 'tertiary')
|
|
131
|
+
- `CircleButton` - Circular icon button
|
|
132
|
+
- `SquareButton` - Square icon button
|
|
133
|
+
- `PillButton` - Pill-shaped button
|
|
134
|
+
|
|
135
|
+
### Form Inputs
|
|
136
|
+
- `InputField` - Compound form input (see sub-components above)
|
|
137
|
+
- `TextInput` - Simple text input
|
|
138
|
+
- `TextArea` - Multi-line input
|
|
139
|
+
- `Checkbox` - Boolean selection
|
|
140
|
+
- `RadioButton` - Single selection
|
|
141
|
+
- `SelectInput` - Dropdown
|
|
142
|
+
- `ToggleSwitch` - On/off switch
|
|
143
|
+
- `PasswordInput` - Password with toggle
|
|
144
|
+
- `PhoneNumber` - Phone with country code
|
|
145
|
+
- `DateOfBirth` - Date input
|
|
146
|
+
- `CountryPicker` - Country dropdown
|
|
147
|
+
- `Stepper` - Increment/decrement
|
|
148
|
+
|
|
149
|
+
### Feedback
|
|
150
|
+
- `Toast` - Temporary notification
|
|
151
|
+
- `AlertBox` - Inline alert (status: 'info' | 'success' | 'warning' | 'danger')
|
|
152
|
+
- `LoadingSpinner` - Loading indicator
|
|
153
|
+
- `Skeleton` - Loading placeholder
|
|
154
|
+
- `ErrorMessage` - Error text
|
|
155
|
+
- `SuccessMessage` - Success text
|
|
156
|
+
- `Badge` - Status label
|
|
157
|
+
- `Tooltip` - Hover tooltip
|
|
158
|
+
|
|
159
|
+
### Typography
|
|
160
|
+
- `TextStyle` - Styled text spans
|
|
161
|
+
- `TitleHeading` - Page titles
|
|
162
|
+
- `DisplayHeading` - Hero text
|
|
163
|
+
- `Link` - Styled links
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
## Spacing Tokens
|
|
168
|
+
|
|
169
|
+
Use spacing tokens instead of pixel values:
|
|
170
|
+
|
|
171
|
+
```tsx
|
|
172
|
+
import { spacing } from '@jamesodwyer/gds-figma-vite';
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
| Token | Value | Usage |
|
|
176
|
+
|-------|-------|-------|
|
|
177
|
+
| `spacing.lounge` | 4px | Tight spacing, icon gaps |
|
|
178
|
+
| `spacing.club` | 8px | Small gaps |
|
|
179
|
+
| `spacing.hall` | 12px | Small padding |
|
|
180
|
+
| `spacing.auditorium` | 16px | Default padding |
|
|
181
|
+
| `spacing.theatre` | 20px | Medium spacing |
|
|
182
|
+
| `spacing.amphitheatre` | 24px | Large padding |
|
|
183
|
+
| `spacing.arena` | 32px | Section spacing |
|
|
184
|
+
| `spacing.stadium` | 48px | Large sections |
|
|
185
|
+
| `spacing.dome` | 64px | Page sections |
|
|
186
|
+
| `spacing.field` | 88px | Hero spacing |
|
|
187
|
+
|
|
188
|
+
```tsx
|
|
189
|
+
import styled from 'styled-components';
|
|
190
|
+
import { spacing } from '@jamesodwyer/gds-figma-vite';
|
|
191
|
+
|
|
192
|
+
const Container = styled.div`
|
|
193
|
+
padding: ${spacing.auditorium};
|
|
194
|
+
gap: ${spacing.club};
|
|
195
|
+
margin-bottom: ${spacing.arena};
|
|
196
|
+
`;
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
---
|
|
200
|
+
|
|
201
|
+
## Typography (textStyle)
|
|
202
|
+
|
|
203
|
+
Use `textStyle` for consistent typography:
|
|
204
|
+
|
|
205
|
+
```tsx
|
|
206
|
+
import { textStyle } from '@jamesodwyer/gds-figma-vite';
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
| Style | Size | Weight | Usage |
|
|
210
|
+
|-------|------|--------|-------|
|
|
211
|
+
| `textStyle.mauna` | 44-54px | 700 | Hero displays |
|
|
212
|
+
| `textStyle.everest` | 32-44px | 700 | Page titles |
|
|
213
|
+
| `textStyle.kilimanjaro` | 24-32px | 700 | Section headers |
|
|
214
|
+
| `textStyle.matterhorn` | 24-28px | 700 | Large headings |
|
|
215
|
+
| `textStyle.vinson` | 22-24px | 700 | Subheadings |
|
|
216
|
+
| `textStyle.blanc` | 18-20px | 700 | Small headers |
|
|
217
|
+
| `textStyle.fiji` | 18px | 600 | Emphasized body |
|
|
218
|
+
| `textStyle.rainier` | 16px | 400 | Body text (default) |
|
|
219
|
+
| `textStyle.etna` | 14px | 400 | Small text |
|
|
220
|
+
| `textStyle.snowdon` | 12px | 600 | Labels/captions |
|
|
221
|
+
|
|
222
|
+
```tsx
|
|
223
|
+
import styled from 'styled-components';
|
|
224
|
+
import { textStyle } from '@jamesodwyer/gds-figma-vite';
|
|
225
|
+
|
|
226
|
+
const Title = styled.h1`
|
|
227
|
+
${textStyle.everest}
|
|
228
|
+
`;
|
|
229
|
+
|
|
230
|
+
const Body = styled.p`
|
|
231
|
+
${textStyle.rainier}
|
|
232
|
+
`;
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
---
|
|
236
|
+
|
|
237
|
+
## Elevation (Shadows)
|
|
238
|
+
|
|
239
|
+
```tsx
|
|
240
|
+
import { elevation } from '@jamesodwyer/gds-figma-vite';
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
| Level | Usage |
|
|
244
|
+
|-------|-------|
|
|
245
|
+
| `elevation.level0` | Default (no shadow) |
|
|
246
|
+
| `elevation.level1` | Cards, content blocks |
|
|
247
|
+
| `elevation.level2` | Sticky headers |
|
|
248
|
+
| `elevation.level3` | Multiple sticky elements |
|
|
249
|
+
| `elevation.level4` | Modals, dialogs |
|
|
250
|
+
|
|
251
|
+
```tsx
|
|
252
|
+
const Card = styled.div`
|
|
253
|
+
${elevation.level1}
|
|
254
|
+
background: white;
|
|
255
|
+
`;
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
## Theme Colors
|
|
261
|
+
|
|
262
|
+
Access colors through theme props:
|
|
263
|
+
|
|
264
|
+
```tsx
|
|
265
|
+
const Component = styled.div`
|
|
266
|
+
background: ${props => props.theme.base.bg};
|
|
267
|
+
color: ${props => props.theme.text.primary};
|
|
268
|
+
border-color: ${props => props.theme.base.border};
|
|
269
|
+
|
|
270
|
+
&.error { color: ${props => props.theme.status.danger}; }
|
|
271
|
+
&.success { color: ${props => props.theme.status.success}; }
|
|
272
|
+
`;
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
### Theme Color Categories
|
|
276
|
+
- `theme.base.primary` - Brand primary color
|
|
277
|
+
- `theme.base.bg` - Background
|
|
278
|
+
- `theme.base.border` - Border color
|
|
279
|
+
- `theme.text.primary` - Primary text
|
|
280
|
+
- `theme.text.secondary` - Secondary text
|
|
281
|
+
- `theme.status.success` - Success green
|
|
282
|
+
- `theme.status.danger` - Error red
|
|
283
|
+
- `theme.status.warning` - Warning yellow
|
|
284
|
+
|
|
285
|
+
---
|
|
286
|
+
|
|
287
|
+
## Icons
|
|
288
|
+
|
|
289
|
+
Import icons directly:
|
|
290
|
+
|
|
291
|
+
```tsx
|
|
292
|
+
import { HeartIcon, CheckmarkIcon, CloseIcon } from '@jamesodwyer/gds-figma-vite';
|
|
293
|
+
|
|
294
|
+
// Usage
|
|
295
|
+
<HeartIcon size="24" />
|
|
296
|
+
<Button startIcon={<CheckmarkIcon />}>Confirm</Button>
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Icon props: `size` (string like "24" or "1.5rem"), `fillColor` (optional)
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Button Props
|
|
304
|
+
|
|
305
|
+
```tsx
|
|
306
|
+
<Button
|
|
307
|
+
colorVariant="primary" // 'primary' | 'secondary' | 'tertiary'
|
|
308
|
+
fullWidth={false} // boolean
|
|
309
|
+
disabled={false} // boolean
|
|
310
|
+
startIcon={<Icon />} // ReactNode
|
|
311
|
+
endIcon={<Icon />} // ReactNode
|
|
312
|
+
onClick={() => {}} // function
|
|
313
|
+
>
|
|
314
|
+
Button Text
|
|
315
|
+
</Button>
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
---
|
|
319
|
+
|
|
320
|
+
## Modal Props
|
|
321
|
+
|
|
322
|
+
```tsx
|
|
323
|
+
<Modal
|
|
324
|
+
isOpen={true} // boolean
|
|
325
|
+
onClose={() => setOpen(false)} // function (required)
|
|
326
|
+
ariaLabel="Modal title" // string (required)
|
|
327
|
+
mobileMaxViewportWidth="768px" // string (required)
|
|
328
|
+
role="dialog" // 'dialog' | 'alertdialog'
|
|
329
|
+
size="standard" // 'standard' | 'large'
|
|
330
|
+
variant="default" // 'default' | 'danger'
|
|
331
|
+
>
|
|
332
|
+
<Modal.Header>
|
|
333
|
+
<Modal.Title>Title</Modal.Title>
|
|
334
|
+
<Modal.CloseButton label="Close modal" />
|
|
335
|
+
</Modal.Header>
|
|
336
|
+
<Modal.Content>
|
|
337
|
+
<Modal.Description>Content</Modal.Description>
|
|
338
|
+
</Modal.Content>
|
|
339
|
+
<Modal.Actions>
|
|
340
|
+
<Button colorVariant="secondary">Cancel</Button>
|
|
341
|
+
<Button colorVariant="primary">Confirm</Button>
|
|
342
|
+
</Modal.Actions>
|
|
343
|
+
</Modal>
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
---
|
|
347
|
+
|
|
348
|
+
## InputField Props
|
|
349
|
+
|
|
350
|
+
```tsx
|
|
351
|
+
<InputField id="fieldId"> {/* id is required */}
|
|
352
|
+
<InputField.Label>Label Text</InputField.Label>
|
|
353
|
+
<InputField.Row marginTop="club">
|
|
354
|
+
<InputField.Input
|
|
355
|
+
type="text" // 'text' | 'email' | 'password' | etc.
|
|
356
|
+
placeholder="..."
|
|
357
|
+
isErrored={false} // boolean - shows error styling
|
|
358
|
+
/>
|
|
359
|
+
</InputField.Row>
|
|
360
|
+
<InputField.Validation
|
|
361
|
+
type="error" // 'error' | 'success'
|
|
362
|
+
screenReaderErrorPrefix="Error:"
|
|
363
|
+
>
|
|
364
|
+
Error message here
|
|
365
|
+
</InputField.Validation>
|
|
366
|
+
</InputField>
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
---
|
|
370
|
+
|
|
371
|
+
## Code Generation Rules
|
|
372
|
+
|
|
373
|
+
### DO:
|
|
374
|
+
- Wrap with `GdsProvider`
|
|
375
|
+
- Use compound component syntax (`Modal.Header`, `Card.Body`)
|
|
376
|
+
- Use spacing tokens (`spacing.auditorium`)
|
|
377
|
+
- Use textStyle for typography
|
|
378
|
+
- Use theme colors (`props.theme.base.primary`)
|
|
379
|
+
|
|
380
|
+
### DO NOT:
|
|
381
|
+
- Import sub-components separately (use dot notation)
|
|
382
|
+
- Use components that don't exist (ButtonGroup, CardContent, etc.)
|
|
383
|
+
- Hardcode hex colors
|
|
384
|
+
- Hardcode pixel values for spacing
|
|
385
|
+
- Skip the GdsProvider wrapper
|