Skip to content

Commit cee52d3

Browse files
authored
Merge pull request #43 from ccswbs/tq-iss42
Multicolumn support for long lists and phone format fix
2 parents ae4519b + e1969f3 commit cee52d3

File tree

10 files changed

+115
-10
lines changed

10 files changed

+115
-10
lines changed

.changeset/pre.json

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
{
2+
"mode": "pre",
3+
"tag": "rc",
4+
"initialVersions": {
5+
"@uoguelph/react-components": "1.7.1",
6+
"@uoguelph/storybook": "1.0.2",
7+
"@uoguelph/tailwind-theme": "1.0.2",
8+
"@uoguelph/web-components": "2.0.10"
9+
},
10+
"changesets": [
11+
"two-trams-fetch"
12+
]
13+
}

.changeset/two-trams-fetch.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@uoguelph/react-components': patch
3+
---
4+
5+
Add multicolumn support for long lists and phone format fix

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/react-components/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# @uoguelph/react-components
22

3+
## 1.7.2-rc.0
4+
5+
### Patch Changes
6+
7+
- 9a29fc9: Add multicolumn support for long lists and phone format fix
8+
39
## 1.7.1
410

511
### Patch Changes

packages/react-components/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@uoguelph/react-components",
3-
"version": "1.7.1",
3+
"version": "1.7.2-rc.0",
44
"description": "University of Guelph React Components Library",
55
"type": "module",
66
"scripts": {

packages/react-components/src/components/contact/contact-email.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ export function ContactEmail({ email, className }: ContactEmailProps) {
2323

2424
return (
2525
<div className={`uofg-contact-email-container ${twMerge(container(), className)}`}>
26-
<FontAwesomeIcon icon={faEnvelope} className="uofg-contact-email-icon" />
26+
<FontAwesomeIcon icon={faEnvelope} className="uofg-contact-email-icon me-2" />
2727
<a className={`uofg-contact-email ${link()}`} href={`mailto:${email}`}>
2828
{email}
2929
</a>

packages/react-components/src/components/contact/contact-phone.tsx

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,35 @@ export type ContactPhoneProps = {
1212
extension?: string;
1313
};
1414

15+
/**
16+
* Strips all non-numeric characters from a phone number
17+
* @param phoneNumber - The phone number to clean
18+
* @returns The phone number with only digits
19+
*/
20+
function stripPhoneNumber(phoneNumber: string): string {
21+
return phoneNumber.replace(/\D/g, '');
22+
}
23+
24+
/**
25+
* Formats a phone number to (XXX) XXX-XXXX format
26+
* @param phoneNumber - The phone number to format
27+
* @returns The formatted phone number
28+
*/
29+
function formatPhoneNumber(phoneNumber: string): string {
30+
const cleaned = stripPhoneNumber(phoneNumber);
31+
32+
// Handle different phone number lengths
33+
if (cleaned.length === 10) {
34+
return `(${cleaned.slice(0, 3)}) ${cleaned.slice(3, 6)}-${cleaned.slice(6)}`;
35+
} else if (cleaned.length === 11 && cleaned.startsWith('1')) {
36+
// Remove leading 1 for North American numbers
37+
return `(${cleaned.slice(1, 4)}) ${cleaned.slice(4, 7)}-${cleaned.slice(7)}`;
38+
}
39+
40+
// Return original if it doesn't match expected format
41+
return phoneNumber;
42+
}
43+
1544
/** The ContactPhone component is used to display a phone number. */
1645
export function ContactPhone({ number, extension, className }: ContactPhoneProps) {
1746
const phone = tv({
@@ -23,11 +52,14 @@ export function ContactPhone({ number, extension, className }: ContactPhoneProps
2352

2453
const { container, link } = phone();
2554

55+
const cleanNumber = stripPhoneNumber(number);
56+
const formattedNumber = formatPhoneNumber(number);
57+
2658
return (
2759
<div className={`uofg-contact-phone-container ${twMerge(container(), className)}`}>
28-
<FontAwesomeIcon icon={faPhone} className="uofg-contact-phone-icon" />
29-
<a className={`uofg-contact-phone ${link()}`} href={`tel:${number}${extension ? `;${extension}` : ''}`}>
30-
{number}{extension && <span className="uofg-contact-phone-extension"> - Ext. {extension}</span>}
60+
<FontAwesomeIcon icon={faPhone} className="uofg-contact-phone-icon me-2" />
61+
<a className={`uofg-contact-phone ${link()}`} href={`tel:${cleanNumber}${extension ? `;${extension}` : ''}`}>
62+
{formattedNumber}{extension && <span className="uofg-contact-phone-extension">, Ext. {extension}</span>}
3163
</a>
3264
</div>
3365
);

packages/react-components/src/components/list/list-item.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ type ListItemProps = PropsWithChildren<
1313
/** A list item component. */
1414
export function ListItem({ className, children, ...rest }: ListItemProps) {
1515
return (
16-
<li {...rest} className={`uofg-list-item ${twMerge('relative h-fit w-full', className)}`}>
16+
<li {...rest} className={`uofg-list-item ${twMerge('relative break-inside-avoid', className)}`}>
1717
{children}
1818
</li>
1919
);

packages/react-components/src/components/list/list.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,14 +34,14 @@ export function List<T extends ListElementType = typeof defaultElement>({
3434
const context = useContext(ListContext);
3535

3636
const list = tv({
37-
base: 'relative flex h-fit w-full list-inside flex-col gap-2',
37+
base: 'relative w-full list-outside gap-x-8 pl-6 [&:has(li:nth-child(9))]:md:columns-2 [&:has(li:nth-child(9))]:xl:columns-3 [&:has(.uofg-list)]:columns-1!',
3838
variants: {
3939
as: {
4040
ol: 'list-decimal',
4141
ul: 'list-disc',
4242
},
4343
nested: {
44-
true: 'ml-4',
44+
true: 'ml-4 columns-1!',
4545
},
4646
level: {
4747
0: '',

packages/storybook/stories/react-components/list.stories.tsx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,3 +103,52 @@ export const NestedOrderedList: Story = {
103103
</List>
104104
),
105105
};
106+
107+
export const LongList: Story = {
108+
args: {
109+
as: 'ul',
110+
},
111+
render: ({ ...args }) => (
112+
<div className="w-full">
113+
<List {...args}>
114+
<ListItem>Introduction to responsive design and modern web development practices</ListItem>
115+
<ListItem>Understanding CSS grid systems and layout fundamentals</ListItem>
116+
<ListItem>Flexbox fundamentals and practical use cases in component design</ListItem>
117+
<ListItem>CSS multicolumn layout properties and browser support considerations</ListItem>
118+
<ListItem>Responsive typography principles for scalable interfaces</ListItem>
119+
<ListItem>Mobile-first design strategies and progressive enhancement</ListItem>
120+
<ListItem>Accessibility considerations and inclusive design patterns</ListItem>
121+
<ListItem>Performance optimization techniques for modern web applications</ListItem>
122+
<ListItem>Cross-browser compatibility testing and fallback strategies</ListItem>
123+
<ListItem>Modern CSS features and graceful degradation approaches</ListItem>
124+
<ListItem>Component-based architecture and design system implementation</ListItem>
125+
<ListItem>User experience best practices for responsive layouts</ListItem>
126+
<ListItem>Testing methodologies for responsive components</ListItem>
127+
<ListItem>Documentation strategies for component libraries</ListItem>
128+
<ListItem>Version control practices for design systems</ListItem>
129+
</List>
130+
</div>
131+
),
132+
};
133+
134+
export const LongOrderedList: Story = {
135+
args: {
136+
as: 'ol',
137+
},
138+
render: ({ ...args }) => (
139+
<List {...args}>
140+
<ListItem>Begin by analyzing the project requirements and scope</ListItem>
141+
<ListItem>Create a detailed project timeline with milestones and deliverables</ListItem>
142+
<ListItem>Set up the development environment and necessary tools</ListItem>
143+
<ListItem>Design the component architecture and establish coding standards</ListItem>
144+
<ListItem>Implement the core functionality with proper testing coverage</ListItem>
145+
<ListItem>Conduct thorough testing across different devices and browsers</ListItem>
146+
<ListItem>Optimize performance and ensure accessibility compliance</ListItem>
147+
<ListItem>Document the implementation and create usage examples</ListItem>
148+
<ListItem>Perform code review and address any identified issues</ListItem>
149+
<ListItem>Deploy to staging environment for final validation</ListItem>
150+
<ListItem>Release to production with proper monitoring in place</ListItem>
151+
<ListItem>Gather feedback and plan for future iterations</ListItem>
152+
</List>
153+
),
154+
};

0 commit comments

Comments
 (0)