Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
…into v2
  • Loading branch information
tonghauhive committed Aug 1, 2024
2 parents c4521c6 + b837b5f commit fa618ee
Show file tree
Hide file tree
Showing 11 changed files with 220 additions and 13 deletions.
1 change: 1 addition & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const parameters = {
order: [
'Getting Started',
['Introduction', 'Installation', 'Usage', 'Frameworks'],
'Troubleshooting',
'Components',
],
},
Expand Down
10 changes: 9 additions & 1 deletion .storybook/static/global.css
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,13 @@
border: none;
background-color: #f6f7fb;
border-radius: 24px;
height: 100%;
}

/* FAQ stylings */
sgds-faq-grid{
display: grid;
grid-template-columns: 3fr 1fr;
row-gap: 1rem;
column-gap: 2rem;
width: 100%;
}
2 changes: 2 additions & 0 deletions amplify.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ frontend:
phases:
preBuild:
commands:
- nvm install 16
- nvm use 16
- rm -rf node_modules && npm ci
build:
commands:
Expand Down
11 changes: 8 additions & 3 deletions src/Badge/Badge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ export interface BadgeProps
textIndicator?: boolean;
/**Controls badge position to the corner of a Component. Use with Component as a wrapper with `.position-relative `css */
dotIndicator?: boolean;
/** Sets the badge to a outlined style badge */
outlined? : boolean;
}

const propTypes = {
Expand Down Expand Up @@ -49,19 +51,21 @@ const propTypes = {
as: PropTypes.elementType,
textIndicator: PropTypes.bool,
dotIndicator: PropTypes.bool,
outlined: PropTypes.bool
};

const defaultProps = {
bg: 'primary',
pill: false,
textIndicator: false,
dotIndicator: false
dotIndicator: false,
outlined: false
};

export const Badge: BsPrefixRefForwardingComponent<'span', BadgeProps> =
React.forwardRef<HTMLElement, BadgeProps>(
(
{ bsPrefix, bg, pill, text, className, textIndicator, dotIndicator, as: Component = 'span', ...props },
{ bsPrefix, bg, pill, text, className, textIndicator, dotIndicator, outlined, as: Component = 'span', ...props },
ref,
) => {
const prefix = useBootstrapPrefix(bsPrefix, 'badge');
Expand All @@ -77,7 +81,8 @@ export const Badge: BsPrefixRefForwardingComponent<'span', BadgeProps> =
text && `text-${text}`,
bg && `bg-${bg}`,
(textIndicator || dotIndicator) && 'position-absolute top-0 start-100 translate-middle',
dotIndicator && 'p-2 border border-light rounded-circle'
dotIndicator && 'p-2 border border-light rounded-circle',
outlined && "badge-light"
)}
>
{dotIndicator && <span className='visually-hidden'>New alerts</span> }
Expand Down
4 changes: 3 additions & 1 deletion src/SideNav/SideNavButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,9 @@ export const SideNavButton: BsPrefixRefForwardingComponent<
aria-haspopup="menu"
className={classNames(
className,
setCollapseCSS(activeEventKey, eventKey)
setCollapseCSS(activeEventKey, eventKey),
// add active class when sidenav item is open or when multiple side nav items are open during alwaysOpen
(eventKey === activeEventKey || activeEventKey?.includes(eventKey)) && "active"
)}
>
{children}
Expand Down
2 changes: 1 addition & 1 deletion src/Stepper/Stepper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { useCallbackRef } from '@restart/hooks';
import { SGDSWrapper } from '../ThemeProvider/ThemeProvider';
import PropTypes from 'prop-types';

export interface StepperProps {
export interface StepperProps {
methods: UseStepMethods;
}

Expand Down
35 changes: 35 additions & 0 deletions stories/components/Badge/Badge.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,41 @@ Add any of the below mentioned modifier classes to change the appearance of a ba
</Story>
</Canvas>

## Outlined

Use the `outlined` prop to achieve a outlined badge with background subtle, border and text emphasis.

<Canvas>
<Story name="Outlined">
<div>
<Badge bg="primary" outlined>
Primary
</Badge>
<Badge bg="secondary" outlined>
Secondary
</Badge>
<Badge bg="success" outlined>
Success
</Badge>
<Badge bg="danger" outlined>
Danger
</Badge>
<Badge bg="warning" outlined>
Warning
</Badge>
<Badge bg="info" outlined>
Info
</Badge>
<Badge bg="light" text="dark" outlined>
Light
</Badge>
<Badge bg="dark" outlined>
Dark
</Badge>
</div>
</Story>
</Canvas>

## Pills

You may also use the pill modifier class to make badges more rounded (with a larger border-radius).
Expand Down
5 changes: 3 additions & 2 deletions stories/components/Navigation/SideNav.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -155,8 +155,9 @@ export const ActiveKeyTemplate = (initialAK, initialALK) => {
);
};
};
const ManageActiveState = ActiveKeyTemplate('', '');
const ActiveLink = ActiveKeyTemplate('0', 'nl-2');

export const ManageActiveState = ActiveKeyTemplate('', '');
export const ActiveLink = ActiveKeyTemplate('0', 'nl-2');

# SideNav

Expand Down
79 changes: 79 additions & 0 deletions stories/troubleshooting/troubleshooting.stories.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { Meta, Description } from '@storybook/addon-docs';
import {
Accordion,
AccordionItem,
AccordionHeader,
AccordionBody,
Card,
CardBody,
CardTitle,
CardText,
CardLink,
} from '../../src/index';

<Meta title="Troubleshooting/FAQ" />

# FAQ page

<br />

<sgds-faq-grid class="mt-2">
<div>
<h3> Components </h3>
<Accordion>
<AccordionItem eventKey="0-components">
<AccordionHeader>
Where can I find the Masthead component?
</AccordionHeader>
<AccordionBody>
<p>
The Masthead components sits in the <code>@govtechsg/sgds-web-component</code> library.
See <a href="https://github.com/GovTechSG/sgds-govtech-react/issues/249#issuecomment-2247209504" target="_blank">answer</a>
</p>
</AccordionBody>
</AccordionItem>
</Accordion>
<h3> Unit Test </h3>
<Accordion>
<AccordionItem eventKey="0-unittest">
<AccordionHeader>
Jest encounters an unexpected token, cannot use import statement outside of a module
</AccordionHeader>
<AccordionBody>
<p> As Jest's support for ES modules are still experimental, you need to include <code>@govtechsg/sgds-react</code> package into <code>transformIgnorePatterns</code> in jest configuration.</p>
<p>Depending on your application's setup, be careful of where your application is reading jest configuration from. For example, <a href="https://create-react-app.dev/docs/running-tests/#configuration" target="_blank">Create-React-App reads jest configuration from package.json by default </a>.
If your test scripts are not configured to point to a separate jest.config.js file, the default configuration for jest in package.json will take precedence.</p>
<p> For users compiling Jest with Babel, see solution <a target="_blank" href="https://github.com/GovTechSG/sgds-govtech-react/issues/202#issuecomment-1816602738">here</a></p>
<p> For NEXTJS users, using next/jest to configure jest, see solution <a target="_blank" href="https://github.com/GovTechSG/sgds-govtech-react/issues/202#issuecomment-1842564757">here</a></p>
</AccordionBody>

</AccordionItem>
</Accordion>
<h3> NextJS </h3>
<Accordion>
<AccordionItem eventKey="0-nextjs">
<AccordionHeader>
I would like to apply Next Link to SGDS anchor-tag components
</AccordionHeader>
<AccordionBody>
<p>
You can use Next Link with SGDS anchor-tag components by wrapping Next Link and assigning the href to Next Link instead of SGDS anchor-tag component. See NextJS documentation <a href="https://nextjs.org/docs/pages/api-reference/components/link#if-the-child-is-a-custom-component-that-wraps-an-a-tag" target="_blank">here</a>
</p>
</AccordionBody>
</AccordionItem>
</Accordion>
</div>
<div>
<Card className="intro-cards">
<CardBody>
<CardTitle as="h4">Github Issues</CardTitle>
<CardText>
Head to GitHub to view or open a new issue
</CardText>
<CardLink href="https://github.com/GovTechSG/sgds-govtech-react/issues/" target="_blank">
Learn more
</CardLink>
</CardBody>
</Card>
</div>
</sgds-faq-grid>
10 changes: 10 additions & 0 deletions tests/Badge/Badge.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,16 @@ describe('Badge', () => {
const badge = getByTestId('test');
expect(badge.querySelector('bg-primary')).toBeNull();
});
it('.badge-light added when outlined is true', () => {
const { getByTestId } = render(
<Badge outlined data-testid="test">
Message
</Badge>,
);

const badge = getByTestId('test');
expect(badge.classList).toContain("badge-light");
});

it('textIndicator prop', () => {
const { getByTestId } = render(
Expand Down
74 changes: 69 additions & 5 deletions tests/SideNav/SideNav.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,21 +247,29 @@ describe('<SideNav>', () => {
});
});

const Component = () => {
const [activeKey, setActiveKey] = useState('1');
interface ComponentProps{
alwaysOpen: boolean;
initialActiveKey: string | string[]
}
const Component = ({alwaysOpen, initialActiveKey}: ComponentProps) => {
const [activeKey, setActiveKey] = useState(initialActiveKey);
const [activeLinkKey, setActiveLinkKey] = useState('two-1');
const clickLink = (key: string) => {
setActiveLinkKey(key);
};
const clickButton = (key: string) => {
activeKey === key ? setActiveKey('') : setActiveKey(key);
if(Array.isArray(initialActiveKey)){
!initialActiveKey.includes(key) ? initialActiveKey.push(key) : null
} else {
activeKey === key ? setActiveKey('') : setActiveKey(key);
}
};
const clickButtonLink = (key: string) => {
setActiveLinkKey('');
clickButton(key);
};
return (
<SideNav activeNavLinkKey={activeLinkKey} activeKey={activeKey}>
<SideNav activeNavLinkKey={activeLinkKey} activeKey={activeKey} alwaysOpen={alwaysOpen} defaultActiveKey={initialActiveKey}>
<SideNav.Item eventKey="0">
<SideNav.Button onClick={() => clickButton('0')}>
SideNav Item #1
Expand Down Expand Up @@ -321,7 +329,7 @@ const Component = () => {

describe('SideNav behaviour when there are active SideNavLink', () => {
it('on first load, second navitem should be expanded', async () => {
const { container, getByText } = render(<Component />);
const { container, getByText } = render(<Component alwaysOpen={false} initialActiveKey="1"/>);
// second nav item is open and first nav item is closed
expect(container.querySelectorAll('.show').length).toEqual(1);
expect(container.querySelectorAll('.btn')[1].classList).not.toContain(
Expand Down Expand Up @@ -355,3 +363,59 @@ describe('SideNav behaviour when there are active SideNavLink', () => {
);
});
});

describe('Active style added to Sidenav when ', () => {
it("on click on sidenav button in normal mode", async() => {
const { container, getByText } = render(<Component alwaysOpen={false} initialActiveKey="1"/>);

expect(container.querySelectorAll('.btn')[1].classList).toContain(
'active'
);
expect(container.querySelectorAll('.btn')[0].classList).not.toContain(
'active'
);
expect(container.querySelectorAll('.btn')[2].classList).not.toContain(
'active'
);

fireEvent.click(getByText('SideNav Item #1'));
await waitFor(() => {
expect(container.querySelectorAll('.btn')[0].classList).toContain(
'active'
);
expect(container.querySelectorAll('.btn')[1].classList).not.toContain(
'active'
);
expect(container.querySelectorAll('.btn')[2].classList).not.toContain(
'active'
);
});
})
it("on click on sidenav button in alwaysOpen mode", async() => {
const { container } = render(<Component alwaysOpen={true} initialActiveKey={["0", "1"]}/>);

expect(container.querySelectorAll('.btn')[1].classList).toContain(
'active'
);
expect(container.querySelectorAll('.btn')[0].classList).toContain(
'active'
);
expect(container.querySelectorAll('.btn')[2].classList).not.toContain(
'active'
);

// fireEvent.click(getByText('SideNav Item #1'));
// await waitFor(() => {
// expect(container.querySelectorAll('.btn')[0].classList).toContain(
// 'active'
// );
// expect(container.querySelectorAll('.btn')[1].classList).toContain(
// 'active'
// );
// expect(container.querySelectorAll('.btn')[2].classList).not.toContain(
// 'active'
// );
// });
})

})

0 comments on commit fa618ee

Please sign in to comment.