Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tabs don't work on desktop #23

Open
72gm opened this issue Nov 24, 2022 · 9 comments
Open

Tabs don't work on desktop #23

72gm opened this issue Nov 24, 2022 · 9 comments

Comments

@72gm
Copy link

72gm commented Nov 24, 2022

Your sample HTML for tabs is missing a few things for the desktop version e.g. js-initialised and the classes to hide content tabs

Not sure what else is missing as the tabs won't switch - can you advise and update your documentation?

It still doesn't appear to work if I copy your actual running example code (not the sample code) so there may be something wrong with the JS also? ... another team in my org had tried this and ended up just using React Bootstrap Tab component as were unable to get this to work

A bit of clarity on this would be good.

thanks

@jsutcliffe
Copy link
Member

Hello, it sounds like you're not initialising the tabs component. The 'js-initialised' class is added by JavaScript when the component is set up.

If you are including the compiled pattern-library.js file, you would want to do something like:

const tabSets = [].slice.call(document.querySelectorAll('[data-module="ds-tabs"]'));
tabSets.forEach(tabSet => new window.DS.components.Tabs(tabSet).init());

Alternatively, calling window.DS.initAll(myElement) will initialise all Design System components inside 'myElement' ('myElement' defaults to window.document if it's not specified).

@72gm
Copy link
Author

72gm commented Feb 7, 2023

Hi,

Can you provide advice on how to best import the JS into a React Typescript app?

We've had a few issues trying to get this to work so have written our own as and when we need it but going forward I'm not sure that is the best solution?

Thanks

@jsutcliffe
Copy link
Member

We do not have any React expertise on the team I'm afraid. However, we are considering a move to TypeScript.

Component scripts are written as ES6 modules and can be found in the /src folder, if that helps at all. That is likely to change if we move to TypeScript, after which we would have the .ts files in /src and provide compiled JS for each component elsewhere.

@72gm
Copy link
Author

72gm commented Feb 9, 2023

If we load the javascript that is in the dist folder via a script tag it doesn't work in the application - I'm guessing because it is SIF and it would need the html to be there to attach whatever functionality it needs to attach? Which isn't going to work in a dynamic SPA? right?

The stuff that's in the src folder doesn't seem to import properly so we are probably quicker writing our own as and when required

Or am I misunderstanding?

Thanks

@jsutcliffe
Copy link
Member

The JavaScript file doesn't do anything on its own, but it does add a "DS" object to the global scope. When your page is ready to set up the components, you can do window.DS.initAll().

window.DS.initAll();

You can also do that whenever the view in your SPA changes and you need to set up new components, and restrict it to the new part of the page.

window.DS.initAll(myNewSection);

If you need finer control, the classes for each component are in window.DS.components. If you wanted to set up some new accordions, for example, you would select them and then initialise them.

const myNewAccordions = [].slice.call(myNewSection.querySelectorAll('[data-module="ds_accordion"]'));
myNewAccordions.forEach(accordion => new window.DS.components.Accordion(accordion).init());

@72gm
Copy link
Author

72gm commented Mar 24, 2023

sorry meant to say... we can't do that in typescript as the DS doesn't exist at design time so we would need a different solution.. couple of teams in the org haven't been able to get this to work

@72gm
Copy link
Author

72gm commented Mar 28, 2023

tried the following after looking at the GDS guidance

image

It loaded the JS according to the Network tab but still doesn't appear to work

@lewisdorigoSoSec
Copy link

@72gm I think the reason that might not work is that — because React does client-side rendering of components — you may find that the elements don't exist in the DOM at the time you're running window.DS.initAll().

If you're using the design system with React, the way we've implemented this at Social Security Scotland is to import the relevant script for each component, and init based on a ref. For example, something like this:

import React, { useEffect, useRef } from 'react';
import DesignSystemTabs from '@scottish-government/design-system/src/components/tabs/tabs';

export const Tabs:ReactFC<SocialSecurityScotland.Components.Tabs> = function Tabs({
    // …props
}) {
    const tabsRef = useRef(null);

    /*
     * When component mounts, if we're in a user-space, and if the ref is set, initialise
     * the component.
     * 
     * The `tabsRef` dependency means this will only run if `tabsRef` changes. 
     */
    useEffect(() => {
        if (tabsRef.current && typeof window !== 'undefined') {
            new DesignSystemTabs(tabsRef.current).init();
        }
    }, [tabsRef]);

    return (
        <div className="ds_tabs" ref={tabsRef}>
            { /* rest of tabs code goes here */ }
        </div>
    ); 
}

export default Tabs;

@72gm
Copy link
Author

72gm commented Jun 10, 2024

@lewisdorigoSoSec yeah absolutely was... we tried a couple of ways, none satisfactory, so we just wrote our own as there wasn't much ;)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants