@papillonarts/components 0.39.0 → 0.40.0

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.
Files changed (36) hide show
  1. package/build/Legacy/Alert/Alert.type.d.ts.map +1 -1
  2. package/build/Legacy/Alert/Alert.type.js +3 -1
  3. package/build/Legacy/Alert/__tests__/Alert.doc.md +74 -41
  4. package/build/Legacy/Blankslate/__tests__/Blankslate.doc.md +60 -22
  5. package/build/Legacy/Breadcrumb/__tests__/Breadcrumb.doc.md +39 -13
  6. package/build/Legacy/Button/__tests__/Button.doc.md +339 -0
  7. package/build/Legacy/Dropdown/__tests__/Dropdown.doc.md +54 -0
  8. package/build/Legacy/ErrorBoundary/ErrorBoundary.type.d.ts.map +1 -1
  9. package/build/Legacy/ErrorBoundary/__tests__/ErrorBoundary.doc.md +33 -0
  10. package/build/Legacy/Form/Checkbox/__tests__/Checkbox.doc.md +87 -0
  11. package/build/Legacy/Form/Input/__tests__/Input.doc.md +84 -0
  12. package/build/Legacy/Form/Radio/__tests__/Radio.doc.md +66 -0
  13. package/build/Legacy/Grid/DisplayTable/__tests__/DisplayTable.doc.md +34 -0
  14. package/build/Legacy/Grid/FlexGrid/FlexGrid.d.ts.map +1 -1
  15. package/build/Legacy/Grid/FlexGrid/FlexGrid.js +3 -6
  16. package/build/Legacy/Grid/FlexGrid/__tests__/FlexGrid.doc.md +158 -0
  17. package/build/Legacy/Icon/__tests__/Icon.doc.md +58 -0
  18. package/build/Legacy/Label/__tests__/Label.doc.md +33 -0
  19. package/build/Legacy/Loader/__tests__/Loader.doc.md +61 -0
  20. package/build/Legacy/Markdown/__tests__/Markdown.doc.md +28 -13
  21. package/build/Legacy/Navigation/Menu/__tests__/Menu.doc.md +53 -0
  22. package/build/Legacy/Navigation/TabNav/__tests__/TabNav.doc.md +99 -0
  23. package/build/Legacy/Navigation/UnderlineNav/__tests__/UnderlineNav.doc.md +106 -0
  24. package/build/Legacy/Pagination/PreviousNext/__tests__/PreviousNext.doc.md +57 -0
  25. package/build/Legacy/Popover/__tests__/Popover.doc.md +260 -0
  26. package/build/Legacy/Progress/__tests__/Progress.doc.md +51 -0
  27. package/build/Legacy/Select/__tests__/Select.doc.md +54 -0
  28. package/build/Legacy/SelectMenu/__tests__/SelectMenu.doc.md +35 -0
  29. package/build/Legacy/Subhead/__tests__/Subhead.doc.md +43 -0
  30. package/build/Legacy/SyntaxHighlighter/__tests__/SyntaxHighlighter.doc.md +45 -21
  31. package/build/Legacy/Toast/__tests__/Toast.doc.md +73 -0
  32. package/build/Modern/Flash/__tests__/Flash.doc.md +151 -6
  33. package/build/Modern/Link/__tests__/Link.doc.md +91 -5
  34. package/build/Modern/Pagination/__tests__/Pagination.doc.md +89 -7
  35. package/build/__tests__/README.md +159 -0
  36. package/package.json +4 -4
@@ -1,11 +1,156 @@
1
- # Flash
1
+ # Features
2
2
 
3
- > Flash component all features
3
+ ```
4
+ Flash all props and variants
5
+ ```
6
+
7
+ ## Props
8
+
9
+ ```typescript
10
+ export type FlashProps = ComponentPropsWithoutRef<'div'> & {
11
+ className?: string
12
+ variant?: 'default' | 'warning' | 'success' | 'danger'
13
+ full?: boolean
14
+ }
15
+ ```
16
+
17
+ ## Variants
18
+
19
+ ```
20
+ Default
21
+
22
+ Success
23
+
24
+ Danger
4
25
 
26
+ Warning
27
+
28
+ Full
29
+
30
+ WithIconAndAction
31
+
32
+ WithIconActionDismiss
33
+ ```
34
+
35
+ ### Default
36
+
37
+ > Flash default variant
38
+
39
+ ```tsx
40
+ <Flash>Default</Flash>
5
41
  ```
6
- # Featues
7
42
 
8
- > Default
9
- > Success, Danger, Warning, Full
10
- > WithIconAndAction, WithIconActionDismiss
43
+ ### Success
44
+
45
+ > Flash success variant
46
+
47
+ ```tsx
48
+ <Flash
49
+ variant="success"
50
+ style={{
51
+ display: 'grid',
52
+ gridTemplateColumns: 'min-content 1fr minmax(0, auto)',
53
+ gridTemplateAreas: `'visual message actions'`,
54
+ }}
55
+ >
56
+ <div className={classes.Visual}>
57
+ <CheckCircleIcon aria-label="Success" />
58
+ </div>
59
+ <div className={classes.Message}>Success</div>
60
+ </Flash>
61
+ ```
62
+
63
+ ### Danger
64
+
65
+ > Flash danger variant
66
+
67
+ ```tsx
68
+ <Flash
69
+ variant="danger"
70
+ style={{
71
+ display: 'grid',
72
+ gridTemplateColumns: 'min-content 1fr minmax(0, auto)',
73
+ gridTemplateAreas: `'visual message actions'`,
74
+ }}
75
+ >
76
+ <div className={classes.Visual}>
77
+ <InfoIcon aria-label="Danger" />
78
+ </div>
79
+ <div className={classes.Message}>Danger</div>
80
+ </Flash>
81
+ ```
82
+
83
+ ### Warning
84
+
85
+ > Flash warning variant
86
+
87
+ ```tsx
88
+ <Flash
89
+ variant="warning"
90
+ style={{
91
+ display: 'grid',
92
+ gridTemplateColumns: 'min-content 1fr minmax(0, auto)',
93
+ gridTemplateAreas: `'visual message actions'`,
94
+ }}
95
+ >
96
+ <div className={classes.Visual}>
97
+ <AlertIcon aria-label="Warning" />
98
+ </div>
99
+ <div className={classes.Message}>Warning</div>
100
+ </Flash>
101
+ ```
102
+
103
+ ### Full
104
+
105
+ > Flash full variant
106
+
107
+ ```tsx
108
+ <Flash
109
+ full
110
+ style={{
111
+ display: 'grid',
112
+ gridTemplateColumns: 'min-content 1fr minmax(0, auto)',
113
+ gridTemplateAreas: `'visual message actions'`,
114
+ }}
115
+ >
116
+ <div className={classes.Visual}>
117
+ <InfoIcon aria-label="Info" />
118
+ </div>
119
+ <div className={classes.Message}>Full</div>
120
+ </Flash>
121
+ ```
122
+
123
+ ### With Icon And Action
124
+
125
+ > Flash with icon and action variant
126
+
127
+ ```tsx
128
+ <Flash className={classes.WithIconAndAction}>
129
+ <div className={classes.Visual}>
130
+ <InfoIcon aria-label="Info" />
131
+ </div>
132
+ <div className={classes.Message}>
133
+ This is a flash message with an icon and an action.
134
+ <Link href="/"> Learn more.</Link>
135
+ </div>
136
+ <div className={classes.ActionsResponsive}>{/*<Button>Join waitlist</Button>*/}</div>
137
+ </Flash>
138
+ ```
139
+
140
+ ### With Icon Action Dismiss
141
+
142
+ > Flash with icon action dismiss variant
143
+
144
+ ```tsx
145
+ <Flash className={classes.WithIconActionDismiss}>
146
+ <div className={classes.Visual}>
147
+ <InfoIcon aria-label="Info" />
148
+ </div>
149
+ <div className={classes.Message}>
150
+ This is a flash message with an icon and an action.
151
+ <Link href="/"> Learn more.</Link>
152
+ </div>
153
+ <div className={classes.ActionsResponsive}>{/*<Button>Join waitlist</Button>*/}</div>
154
+ <div className={classes.Close}>{/*<IconButton variant="invisible" icon={XIcon} aria-label="Dismiss" />*/}</div>
155
+ </Flash>
11
156
  ```
@@ -1,10 +1,96 @@
1
- # Link
1
+ # Features
2
2
 
3
- > Link component all features
3
+ ```
4
+ Link all props and variants
5
+ ```
6
+
7
+ ## Props
8
+
9
+ ```typescript
10
+ type StyledLinkProps<As extends ElementType = 'a'> = {
11
+ as?: As
12
+ /** @deprecated use CSS modules to style hover color */
13
+ hoverColor?: string
14
+ muted?: boolean
15
+ // Link inside a text block
16
+ inline?: boolean
17
+ }
18
+ ```
19
+
20
+ ## Variants
21
+
22
+ ```
23
+ Default
24
+
25
+ Muted
26
+
27
+ Inline1
28
+
29
+ Inline2
30
+ ```
4
31
 
32
+ ### Default
33
+
34
+ > Link default variant
35
+
36
+ ```tsx
37
+ <Link href="#">Links are great</Link>
38
+ ```
39
+
40
+ ### Muted
41
+
42
+ > Link muted variant
43
+
44
+ ```tsx
45
+ <Link href="#" muted>
46
+ Link
47
+ </Link>
5
48
  ```
6
- # Featues
7
49
 
8
- > Default
9
- > Muted, Inline1, Inline2
50
+ ### Inline1
51
+
52
+ > Link inline 1 variant
53
+
54
+ ```tsx
55
+ <Link inline={true} href="#">
56
+ Link
57
+ </Link>
58
+ ```
59
+
60
+ ### Inline2
61
+
62
+ > Link inline 2 variant
63
+
64
+ ```tsx
65
+ <div>
66
+ <div style={{ display: 'flex', flexDirection: 'column' }} data-a11y-link-underlines="true">
67
+ [data-a11y-link-underlines=true] (inline links have underline)
68
+ <Link href="#">inline: undefined</Link>
69
+ <Link inline={true} href="#">
70
+ inline: true
71
+ </Link>
72
+ <Link inline={false} href="#">
73
+ inline: false
74
+ </Link>
75
+ <br />
76
+ <Link muted={true} inline={true} href="#">
77
+ inline: true, muted: true
78
+ </Link>
79
+ </div>
80
+ <br />
81
+ <div style={{ display: 'flex', flexDirection: 'column' }} data-a11y-link-underlines="false">
82
+ [data-a11y-link-underlines=false] (inline has no effect)
83
+ <Link href="#">inline: undefined</Link>
84
+ <Link inline={true} href="#">
85
+ inline: true
86
+ </Link>
87
+ <Link inline={false} href="#">
88
+ inline: false
89
+ </Link>
90
+ <br />
91
+ <Link muted={true} inline={true} href="#">
92
+ inline: true, muted: true
93
+ </Link>
94
+ </div>
95
+ </div>
10
96
  ```
@@ -1,12 +1,94 @@
1
- # Pagination
1
+ # Features
2
2
 
3
- > Pagination component all features
3
+ ```
4
+ Pagination all props and variants
5
+ ```
6
+
7
+ ## Props
8
+
9
+ ```typescript
10
+ export type PaginationProps = {
11
+ className?: string
12
+ pageCount: number
13
+ currentPage: number
14
+ onPageChange?: (e: React.MouseEvent, n: number) => void
15
+ hrefBuilder?: (n: number) => string
16
+ marginPageCount?: number
17
+ showPages?: boolean | ResponsiveValue<boolean>
18
+ surroundingPageCount?: number
19
+ renderPage?: (props: PageProps) => React.ReactNode
20
+ }
21
+ ```
22
+
23
+ ## Variants
24
+
25
+ ```
26
+ Default
27
+
28
+ LargerPageCountMargin
29
+
30
+ HidePageNumbers
31
+
32
+ HidePageNumbersByViewport
33
+
34
+ HigherSurroundingPageCount
35
+
36
+ RenderLinks
37
+ ```
38
+
39
+ ### Default
40
+
41
+ > Pagination default variant
42
+
43
+ ```tsx
44
+ <Pagination pageCount={15} currentPage={2} onPageChange={(e) => e.preventDefault()} showPages={{ narrow: false }} />
45
+ ```
46
+
47
+ ### Larger PageCount Margin
48
+
49
+ > Pagination larger page count margin variant
4
50
 
51
+ ```tsx
52
+ <Pagination pageCount={15} currentPage={5} marginPageCount={4} onPageChange={(e) => e.preventDefault()} />
5
53
  ```
6
- # Featues
7
54
 
8
- > Defaults
9
- > LargerPageCountMargin
10
- > HidePageNumbers, HidePageNumbersByViewport, HigherSurroundingPageCount
11
- > RenderLinks
55
+ ### Hide Page Numbers
56
+
57
+ > Pagination hide page numbers variant
58
+
59
+ ```tsx
60
+ <Pagination pageCount={15} currentPage={5} showPages={false} onPageChange={(e) => e.preventDefault()} />
61
+ ```
62
+
63
+ ### Hide Page Numbers By Viewport
64
+
65
+ > Pagination hide page numbers by viewport variant
66
+
67
+ ```tsx
68
+ <Pagination pageCount={15} currentPage={5} showPages={{ narrow: false }} onPageChange={(e) => e.preventDefault()} />
69
+ <p>Page numbers are hidden on narrow viewports.</p>
70
+ ```
71
+
72
+ ### Higher Surrounding Page Count
73
+
74
+ > Pagination higher surrounding page count variant
75
+
76
+ ```tsx
77
+ <Pagination pageCount={15} currentPage={5} surroundingPageCount={4} onPageChange={(e) => e.preventDefault()} />
78
+ ```
79
+
80
+ ### Render Links
81
+
82
+ > Pagination render links variant
83
+
84
+ ```tsx
85
+ <Pagination
86
+ pageCount={15}
87
+ currentPage={page}
88
+ onPageChange={(e, n) => {
89
+ e.preventDefault()
90
+ setPage(n)
91
+ }}
92
+ renderPage={({ number, ...props }) => <ReactRouterLikeLink to={`#${number}`} {...props} />}
93
+ />
12
94
  ```
@@ -0,0 +1,159 @@
1
+ # Test Environment
2
+
3
+ ## Date Handling
4
+
5
+ All tests use UTC timezone with ISO-like formatting to prevent snapshot drift across different environments and timezones.
6
+
7
+ Date.prototype methods are patched in [jest.setup.js](../../../../jest.setup.js) to ensure deterministic output:
8
+ - `toLocaleString()` → "yyyy-MM-ddTHH:mm:ssZ" (ISO-like, explicit UTC)
9
+ - `toLocaleDateString()` → "yyyy-MM-dd"
10
+ - `toLocaleTimeString()` → "HH:mm:ssZ"
11
+
12
+ **Example:**
13
+ ```javascript
14
+ new Date('2020-07-05T19:04:15Z').toLocaleString() // "2020-07-05T19:04:15Z"
15
+ ```
16
+
17
+ ## Test Scripts
18
+
19
+ - **`npm test`** - Fast parallel execution (no coverage, no snapshot updates)
20
+ - Best for: Local development, quick feedback
21
+ - Workers: 50% of CPU cores
22
+ - Duration: ~49s
23
+
24
+ - **`npm run test:ci`** - Full CI run (serial, coverage, updates snapshots)
25
+ - Best for: CI/CD, pre-commit validation, snapshot updates
26
+ - Workers: 1 (--runInBand for determinism)
27
+ - Duration: ~97s
28
+
29
+ - **`npm run test:coverage`** - Parallel with coverage
30
+ - Best for: Coverage reports without snapshot updates
31
+ - Workers: 50% of CPU cores
32
+ - Duration: ~49s
33
+
34
+ - **`npm run test:tdd`** - Watch mode for local development
35
+ - Best for: Test-driven development
36
+ - Features: Watch mode, verbose output, only changed files
37
+
38
+ - **`npm run test:update-snapshots`** - Update snapshots only
39
+ - Best for: Intentional snapshot updates without full CI run
40
+
41
+ - **`npm run test:generate-output`** - Generate JSON output for Storybook
42
+ - Best for: Storybook integration
43
+
44
+ ## Test Structure
45
+
46
+ ```
47
+ packages/components/src/
48
+ ├── Legacy/
49
+ │ ├── Button/
50
+ │ │ ├── __tests__/
51
+ │ │ │ ├── Button.test.ts # Test file
52
+ │ │ │ └── __snapshots__/ # Snapshot files
53
+ │ │ └── Button.tsx
54
+ │ └── ...
55
+ ├── Modern/
56
+ │ └── ...
57
+ └── __tests__/
58
+ ├── README.md # This file
59
+ └── test-utils.ts # Shared test utilities
60
+ ```
61
+
62
+ ## Test Conventions
63
+
64
+ - **Test files**: `*.test.ts` or `*.test.tsx`
65
+ - **Snapshot files**: Stored in `__snapshots__/` directories
66
+ - **Test utilities**: Shared helpers in `__tests__/test-utils.ts`
67
+
68
+ ## Coverage Thresholds
69
+
70
+ Thresholds reflect the broader instrumentation baseline and are enforced only in CI or when explicitly enabled.
71
+
72
+ | Metric | Threshold | Rationale |
73
+ |-------------|-----------|----------------------------------------------|
74
+ | Statements | 63% | Broader scope including library/lodash |
75
+ | Branches | 60% | Accounts for untested conditional paths |
76
+ | Functions | 52% | Library barrels and type-only exports |
77
+ | Lines | 64% | Matches statements threshold |
78
+
79
+ Enforcement:
80
+ - Local fast dev (`npm test`): thresholds not enforced.
81
+ - Local CI-style (`COVERAGE=true npm run test:ci`): thresholds enforced.
82
+ - CI (`CI=true npm run test:ci`): thresholds enforced.
83
+
84
+ ## Running Tests
85
+
86
+ ### Quick Development Cycle
87
+ ```bash
88
+ npm test # Fast feedback
89
+ npm run test:tdd # Watch mode
90
+ ```
91
+
92
+ ### Before Committing
93
+ ```bash
94
+ npm run test:ci # Full validation with coverage
95
+ ```
96
+
97
+ ### Updating Snapshots
98
+ ```bash
99
+ npm run test:update-snapshots # Update snapshots only
100
+ npm run test:ci # Update + coverage
101
+ ```
102
+
103
+ ## Shared Test Utilities
104
+
105
+ Use helpers from `test-utils.ts` to reduce boilerplate:
106
+
107
+ ```typescript
108
+ import { renderSnapshot, renderSnapshotAsync } from '../__tests__/test-utils'
109
+
110
+ // Synchronous snapshot
111
+ test('must match defaults()', () => {
112
+ renderSnapshot(defaults())
113
+ })
114
+
115
+ // Async snapshot
116
+ test('must match async()', async () => {
117
+ await renderSnapshotAsync(async())
118
+ })
119
+ ```
120
+
121
+ ## Troubleshooting
122
+
123
+ ### Snapshot Drift
124
+ If snapshots keep changing:
125
+ 1. Verify UTC timezone is set (`process.env.TZ = 'UTC'` in jest.setup.js)
126
+ 2. Check date formatting functions are using UTC methods (`getUTCDate()`, not `getDate()`)
127
+ 3. Run `npm run test:ci` to update snapshots with deterministic settings
128
+
129
+ ### Coverage Threshold Failures
130
+ - Local `npm test` does not enforce thresholds; use it for fast development.
131
+ - Use `COVERAGE=true npm run test:ci` to enforce thresholds locally before CI.
132
+ - Coverage thresholds are enforced in CI to maintain code quality.
133
+
134
+ ### Slow Test Execution
135
+ - Use `npm test` instead of `npm run test:ci` for development (2x faster)
136
+ - Use `npm run test:tdd` to run only changed tests
137
+ - Check for heavy setup/teardown in `beforeEach`/`afterEach` hooks
138
+
139
+ ## CI/CD Integration
140
+
141
+ For CI pipelines, always use:
142
+ ```bash
143
+ CI=true npm run test:ci
144
+ ```
145
+
146
+ This ensures:
147
+ - Serial execution for deterministic results
148
+ - Coverage reports for Codecov
149
+ - Snapshot updates are captured
150
+ - Coverage thresholds are enforced
151
+ - Consistent timing measurements
152
+
153
+ ## Shared Utilities
154
+
155
+ Import helpers from this folder to reduce boilerplate:
156
+
157
+ ```ts
158
+ import { renderSnapshot, renderSnapshotAsync, waitFor } from './test-utils'
159
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@papillonarts/components",
3
- "version": "0.39.0",
3
+ "version": "0.40.0",
4
4
  "description": "Papillon Arts Components",
5
5
  "homepage": "https://github.com/papillonarts/papillonarts/tree/master/packages/components",
6
6
  "repository": {
@@ -26,8 +26,8 @@
26
26
  "build-release": "npm run build"
27
27
  },
28
28
  "dependencies": {
29
- "@papillonarts/css": "^0.39.0",
30
- "@papillonarts/library": "^0.39.0"
29
+ "@papillonarts/css": "^0.40.0",
30
+ "@papillonarts/library": "^0.40.0"
31
31
  },
32
- "gitHead": "b8f07f71414d7133bc1cfa967ecf30ebca383ef7"
32
+ "gitHead": "7a19d357d33591ad460a6cb42f18963082beffd8"
33
33
  }