Skip to content

Commit

Permalink
[Bugfix] Modular UI - Fixing Custom and Toggle button styles (#9067)
Browse files Browse the repository at this point in the history
(master → master)
  • Loading branch information
webviewer-ui committed Jun 5, 2024
1 parent 79efcc2 commit d33d387
Show file tree
Hide file tree
Showing 7 changed files with 232 additions and 66 deletions.
40 changes: 34 additions & 6 deletions .storybook/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ const path = require('path');
const appDirectory = path.join(__dirname, '..');

module.exports = {
stories: [
"../src/**/*.stories.mdx",
"../src/**/*.stories.@(js|jsx|ts|tsx)"
],
stories: ['../src/**/*.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
staticDirs: ['./static'],

addons: [
"@storybook/addon-links",
"@storybook/addon-essentials"
"@storybook/addon-essentials",
'@storybook/addon-webpack5-compiler-swc',
'@chromatic-com/storybook',
'@storybook/addon-interactions',
'@storybook/addon-a11y',
'storybook-addon-pseudo-states'
],

webpackFinal: async (config, { configType }) => {
// `configType` has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
Expand Down Expand Up @@ -72,5 +76,29 @@ module.exports = {

return config;
},
framework: '@storybook/react',

framework: {
name: '@storybook/react-webpack5',
options: {}
},

docs: {},

swcLoaderOptions: {
jsc: {
parser: {
syntax: 'ecmascript',
jsx: true,
},
transform: {
react: {
runtime: 'automatic'
}
}
}
},

typescript: {
reactDocgen: 'react-docgen-typescript'
}
}
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@
"sass": "^1.34.0",
"sass-loader": "^8.0.2",
"storybook": "^8.1.0",
"storybook-addon-pseudo-states": "^3.1.1",
"style-loader": "^1.1.3",
"svg-inline-loader": "^0.8.0",
"typescript": "^5.4.5",
Expand All @@ -139,4 +140,4 @@
"webpack-dev-middleware": "^7.2.1",
"webpack-hot-middleware": "^2.26.1"
}
}
}
99 changes: 47 additions & 52 deletions src/components/ModularComponents/AppStories/App.stories.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,62 @@
import React from 'react';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';
import App from 'components/App';
import initialState from 'src/redux/initialState';
import rootReducer from 'reducers/rootReducer';
import { mockHeadersNormalized, mockModularComponents } from './mockAppState';
import { userEvent, within, expect } from '@storybook/test';
import { createTemplate } from 'helpers/storybookHelper';

export default {
title: 'ModularComponents/App',
component: App,
includeStories: ['DefaultUI', 'ActiveGroupHeaderTest', 'HeaderButtonsWithLabelsAndIcons'],
excludeStories: ['CreateTemplate'],
};

const noop = () => { };
export const DefaultUI = createTemplate({ headers: mockHeadersNormalized, components: mockModularComponents });

const MockApp = ({ initialState }) => {
return (
<Provider store={configureStore({
reducer: rootReducer,
preloadedState: initialState,
middleware: (getDefaultMiddleware) => getDefaultMiddleware({ serializableCheck: false })
})}>
<App removeEventHandlers={noop} />
</Provider>
);
export const ActiveGroupHeaderTest = createTemplate({ headers: mockHeadersNormalized, components: mockModularComponents });
ActiveGroupHeaderTest.play = async ({ canvasElement }) => {
const canvas = within(canvasElement);
// We should be able to find the underline button since the default selected group is annotateGroupedItems
await canvas.findAllByRole('button', { name: 'Underline' });
// Now if we click on ribbon
const viewRibbon = await canvas.findByLabelText('View');
await userEvent.click(viewRibbon);
// the underline button should not be visible anymore as the header is hidden
expect(await canvas.queryByRole('button', { name: 'Underline' })).toBeNull();
};

const Template = (args) => {
const stateWithHeaders = {
...initialState,
viewer: {
...initialState.viewer,
modularHeaders: args.headers,
modularComponents: args.components,
openElements: {},
genericPanels: [{
dataElement: 'stylePanel',
render: 'stylePanel',
location: 'left',
}],
activeGroupedItems: ['annotateGroupedItems'],
lastPickedToolForGroupedItems: {
annotateGroupedItems: 'AnnotationCreateTextUnderline',
},
activeCustomRibbon: 'annotations-ribbon-item',
lastPickedToolAndGroup: {
tool: 'AnnotationCreateTextUnderline',
group: ['annotateGroupedItems'],
},
activeToolName: 'AnnotationCreateTextUnderline'
},
featureFlags: {
customizableUI: true,
},
};
return <MockApp initialState={stateWithHeaders} />;
const customHeaders = {
...mockHeadersNormalized,
'default-top-header': {
...mockHeadersNormalized['default-top-header'],
'items': [
...mockHeadersNormalized['default-top-header'].items,
'labelButton',
'labelAndIconButton'
]
}
};

function createTemplate({ headers, components }) {
const template = Template.bind({});
template.args = { headers, components };
template.parameters = { layout: 'fullscreen' };
return template;
}
const labelAndIconButton = {
'dataElement': 'labelAndIconButton',
'title': 'Export button',
'type': 'customButton',
'label': 'Export',
'img': 'icon-save',
'onClick': () => {},
};

export const DefaultUI = createTemplate({ headers: mockHeadersNormalized, components: mockModularComponents });
const labelButton = {
'dataElement': 'labelButton',
'title': 'Toggle the visibility of Flyout',
'type': 'toggleButton',
'label': 'Custom Flyout',
'toggleElement': 'myCustomFlyout'
};

const customComponents = {
...mockModularComponents,
'labelAndIconButton': labelAndIconButton,
'labelButton': labelButton
};

export const HeaderButtonsWithLabelsAndIcons = createTemplate({ headers: customHeaders, components: customComponents });
57 changes: 57 additions & 0 deletions src/components/ModularComponents/CustomButton/CustomButton.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
@import '../../../constants/styles';

.CustomButton {
padding: 5px;
width: fit-content;
min-width: 32px;

&:hover,
&:active {
@extend %custom-button-hover;
}

&:active {
color: var(--view-header-icon-active-fill);
cursor: default;

.Icon svg path {
fill: var(--view-header-icon-active-fill)
}
}
}

.confirm-button {
background-color: var(--primary-button);
border: 1px solid var(--primary-button);
color: var(--primary-button-text);
padding: 7px 14px;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
border-radius: 5px;
height: 30px;
cursor: pointer;

&:hover {
background: var(--primary-button-hover) !important;
border: 1px solid var(--primary-button-hover) !important;
border-radius: 5px !important;
}
}

.cancel-button {
color: var(--secondary-button-text);
background-color: transparent;
padding: 7px 14px;
width: -webkit-fit-content;
width: -moz-fit-content;
width: fit-content;
border-radius: 5px;
height: 30px;
cursor: pointer;

&:hover {
color: var(--secondary-button-hover);
background: transparent;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import React from 'react';
import CustomButton from './CustomButton';
import initialState from 'src/redux/initialState';
import { Provider } from 'react-redux';
import { configureStore } from '@reduxjs/toolkit';

export default {
title: 'Components/CustomButton',
component: CustomButton,
};

const store = configureStore({
reducer: () => initialState
});

const BasicComponent = (props) => {
return (
<Provider store={store}>
<CustomButton {...props} />
</Provider>
);
};

export const DefaultButton = BasicComponent.bind({});
DefaultButton.args = {
dataElement: 'button-data-element',
title: 'Button title',
disabled: false,
label: 'Click',
img: 'icon-save',
onClick: () => {
alert('Clicked!');
}
};

export const DefaultButtonOnHover = BasicComponent.bind({});
DefaultButtonOnHover.args = {
dataElement: 'button-data-element',
title: 'Button title',
disabled: false,
label: 'Click',
img: 'icon-save',
onClick: () => {
alert('Clicked!');
}
};

DefaultButtonOnHover.parameters = {
pseudo: { hover: true },
};

export const ConfirmButton = BasicComponent.bind({});
ConfirmButton.args = {
dataElement: 'button-data-element',
title: 'Apply Fields',
label: 'Apply Fields',
preset: 'confirm',
onClick: () => {
alert('Apply Fields button clicked!');
}
};

export const CancelButton = BasicComponent.bind({});
CancelButton.args = {
dataElement: 'button-data-element',
title: 'Cancel',
label: 'Cancel',
preset: 'cancel',
onClick: () => {
alert('Cancel button clicked!');
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@

.ToggleElementButton {
.Button {
width: 32px;
width: auto;
min-width: 32px;
height: 32px;
padding: 5px;

&:hover {
background: var(--tools-button-hover);
&:hover,
&.active {
@extend %custom-button-hover;
}

&.active {
background: var(--tools-button-active);
color: var(--view-header-icon-active-fill);
cursor: default;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ import { Provider } from 'react-redux';
export default {
title: 'ModularComponents/ToggleElementButton',
component: ToggleElementButton,
parameters: {
customizableUI: true,
},
};

const initialState = {
Expand Down Expand Up @@ -44,8 +47,16 @@ const store = configureStore({

export const ToggleElementButtonComponent = () => (
<Provider store={store}>
<div style={{ width: '32px' }}>
<ToggleElementButton img='icon-header-search' toggleElement='signatureModal' dataElement='toggleButton' />
</div>
<ToggleElementButton img='icon-header-search' toggleElement='signatureModal' dataElement='toggleButton' />
</Provider>
);

export const ToggleElementButtonWithLabelOnHoverState = () => (
<Provider store={store}>
<ToggleElementButton img='icon-header-search' toggleElement='signatureModal' dataElement='toggleButton' label='Toggle Element' />
</Provider>
);

ToggleElementButtonWithLabelOnHoverState.parameters = {
pseudo: { hover: true },
};

0 comments on commit d33d387

Please sign in to comment.