Skip to content

Commit 933e172

Browse files
authored
docs: introduce (UXC) "patterns" section & add design examples for ShellBar (#7411)
1 parent fff9fb9 commit 933e172

39 files changed

+5383
-29
lines changed

.github/renovate.json

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,21 +72,21 @@
7272
]
7373
},
7474
{
75-
"description": "Example & Template dependencies",
75+
"description": "Example,Template & Pattern dependencies",
7676
"extends": ["schedule:weekly"],
77-
"matchFileNames": ["examples/**", "templates/**"],
77+
"matchFileNames": ["examples/**", "templates/**", "patterns/**"],
7878
"semanticCommitType": "chore",
79-
"groupName": "all non-major dependencies (examples & templates)",
79+
"groupName": "all non-major dependencies (examples, templates & patterns)",
8080
"groupSlug": "examples-all-minor-patch",
8181
"matchUpdateTypes": ["minor", "patch"],
8282
"matchBaseBranches": ["main"],
8383
"matchPackageNames": ["*", "!/^@ui5//"]
8484
},
8585
{
86-
"description": "UI5 Web Components (for React) in all examples & templates",
87-
"groupName": "UI5 Web Components React (examples & templates)",
86+
"description": "UI5 Web Components (for React) in all examples, templates & patterns",
87+
"groupName": "UI5 Web Components React (examples, templates & patterns)",
8888
"groupSlug": "examples-ui5-webcomponents-react",
89-
"matchFileNames": ["examples/**", "templates/**"],
89+
"matchFileNames": ["examples/**", "templates/**", "patterns/**"],
9090
"semanticCommitType": "chore",
9191
"matchBaseBranches": ["main"],
9292
"matchSourceUrls": [

.github/workflows/examples.yml

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ on:
77
paths:
88
- 'examples/**/*'
99
- 'templates/**/*'
10+
- 'patterns/navigation-layout/**/*'
1011
pull_request:
1112
paths:
1213
- 'examples/**/*'
1314
- 'templates/**/*'
15+
- 'patterns/navigation-layout/**/*'
1416

1517
jobs:
1618
examples:
@@ -77,3 +79,33 @@ jobs:
7779
- name: ESLint
7880
run: npm run lint --if-present
7981
working-directory: templates/${{ matrix.path }}
82+
83+
patterns:
84+
runs-on: ubuntu-latest
85+
strategy:
86+
matrix:
87+
path:
88+
- navigation-layout
89+
fail-fast: false
90+
steps:
91+
- uses: actions/checkout@v4
92+
93+
- uses: actions/[email protected]
94+
with:
95+
node-version-file: '.nvmrc'
96+
97+
- name: Install
98+
run: npm ci
99+
working-directory: patterns/${{ matrix.path }}
100+
101+
- name: Build
102+
run: npm run build
103+
working-directory: patterns/${{ matrix.path }}
104+
105+
- name: Test
106+
run: npm run test --if-present
107+
working-directory: patterns/${{ matrix.path }}
108+
109+
- name: ESLint
110+
run: npm run lint --if-present
111+
working-directory: patterns/${{ matrix.path }}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## Design-Compliant Examples
2+
3+
These examples demonstrate the implementation of design specifications. They primarily illustrate design concepts and mostly do not provide additional functionality. You can reference them to select the appropriate design patterns.

.storybook/preview.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ const preview: Preview = {
144144
'Knowledge Base',
145145
'Testing with Cypress',
146146
['Setup', 'Commands', 'Queries'],
147+
'Patterns',
147148
'Charts',
148149
['Docs'],
149150
'Data Display',

docs/EmbeddedStackBlitz.tsx

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import sdk from '@stackblitz/sdk';
2+
import { useEffect, useRef } from 'react';
3+
4+
interface EmbeddedStackBlitzProps {
5+
repoPath: string;
6+
}
7+
8+
export function EmbeddedStackBlitz({ repoPath }: EmbeddedStackBlitzProps) {
9+
const containerRef = useRef<HTMLDivElement | null>(null);
10+
11+
useEffect(() => {
12+
const container = containerRef.current;
13+
if (!container) {
14+
return;
15+
}
16+
sdk.embedGithubProject(container, repoPath, {
17+
openFile: 'src/App.tsx',
18+
view: 'editor',
19+
height: '90%',
20+
hideDevTools: true,
21+
terminalHeight: 0,
22+
});
23+
24+
return () => {
25+
if (container) {
26+
container.innerHTML = '';
27+
}
28+
};
29+
}, [repoPath]);
30+
31+
return <div ref={containerRef} />;
32+
}
33+
34+
EmbeddedStackBlitz.displayName = 'EmbeddedStackBlitz';

docs/Patterns.mdx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import {Footer} from '@sb/components';
2+
import {Meta} from '@storybook/blocks';
3+
import UXCIntegration from "./UXCIntegration.js"
4+
5+
<Meta title="Patterns / UXC Integration"/>
6+
7+
# UXC Integration
8+
9+
<UXCIntegration/>
10+
11+
<Footer/>

docs/UXCIntegration.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { MessageStrip, ThemeProvider } from '@ui5/webcomponents-react';
2+
import UXCIntegrationApp from '../patterns/navigation-layout/src/App.js';
3+
import '../patterns/navigation-layout/src/index.css';
4+
import { EmbeddedStackBlitz } from '@/docs/EmbeddedStackBlitz.js';
5+
6+
function UXCIntegration() {
7+
return (
8+
<div style={{ height: '80vh', position: 'relative' }}>
9+
<ThemeProvider>
10+
<UXCIntegrationApp
11+
content={
12+
<>
13+
<MessageStrip hideCloseButton style={{ marginBlockEnd: '0.25rem' }}>
14+
For a full-page view of this pattern, click <b>&#34;Fork on StackBlitz&#34;</b> below to open it in the
15+
standalone StackBlitz editor.
16+
</MessageStrip>
17+
<EmbeddedStackBlitz repoPath="SAP/ui5-webcomponents-react/tree/main/patterns/navigation-layout" />
18+
</>
19+
}
20+
/>
21+
</ThemeProvider>
22+
</div>
23+
);
24+
}
25+
26+
export default UXCIntegration;

eslint.config.mjs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ const ignorePatterns = {
3030
'**/out/**',
3131
'**/examples',
3232
'**/templates',
33+
'**/patterns/navigation-layout',
3334
],
3435
};
3536

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"create-theming-parameters": "node scripts/generate-theming-parameters.js"
3636
},
3737
"dependencies": {
38+
"@stackblitz/sdk": "^1.11.0",
3839
"@storybook/addon-a11y": "8.6.14",
3940
"@storybook/addon-essentials": "8.6.14",
4041
"@storybook/blocks": "8.6.14",

packages/main/src/components/MessageBox/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ export interface MessageBoxPropTypes
4949
* Flag whether the Message Box should be opened or closed
5050
*/
5151
open?: DialogPropTypes['open'];
52+
// todo: add headerText prop and deprecate `titleText`
5253
/**
5354
* A custom title for the MessageBox. If not present, it will be derived from the `MessageBox` type.
5455
*/

packages/main/src/webComponents/ShellBar/ShellBar.mdx

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { ControlsWithNote, DocsHeader, Footer } from '@sb/components';
22
import SubcomponentsSection from '@sb/docs/SubcomponentsSection.md?raw';
3+
import DesignExamples from '@sb/docs/DesignCompliantExampleSection.md?raw';
34
import { ArgTypes, Canvas, Description, Markdown, Meta } from '@storybook/blocks';
45
import { ShellBarItem } from '../ShellBarItem/index';
56
import { ShellBarSpacer } from '../ShellBarSpacer/index';
@@ -21,13 +22,41 @@ import { excludePropsForAbstract } from '@sb/utils';
2122

2223
<ControlsWithNote of={ComponentStories.Default} />
2324

24-
<br />
25+
<Markdown>{DesignExamples}</Markdown>
2526

26-
# More Examples
27+
### All Features
2728

28-
<br />
29+
A comprehensive ShellBar demonstrating all available features including notifications, search, content items, and profile.
30+
31+
<Canvas of={ComponentStories.AllFeatures} />
32+
33+
### Embedded Back Navigation
34+
35+
ShellBar with embedded back navigation button in the start area.
36+
37+
<Canvas of={ComponentStories.EmbeddedBackNavigation} />
38+
39+
### Trial Example
40+
41+
ShellBar configured for trial environments with trial tags and remaining days indicator.
42+
43+
<Canvas of={ComponentStories.TrialExample} />
44+
45+
### Multiple Productive Instances
46+
47+
ShellBar setup for multiple productive system instances with region indicators.
48+
49+
<Canvas of={ComponentStories.ProductiveInstances} />
50+
51+
### Multiple Non-Productive Instances
52+
53+
ShellBar setup for multiple non-productive system instances with system and region tags.
54+
55+
<Canvas of={ComponentStories.NonProductiveInstances} />
56+
57+
## More examples
2958

30-
## Open a Popover on ShellBarItem click
59+
### Open a Popover on ShellBarItem click
3160

3261
To open a popover with the `ShellBarItem` you can use the `detail.targetRef` property of the `onClick` event.
3362

Lines changed: 121 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,17 @@
11
import image from '@sb/demoImages/Person.png';
22
import type { Meta, StoryObj } from '@storybook/react';
3-
import addIcon from '@ui5/webcomponents-icons/dist/add.js';
4-
import searchIcon from '@ui5/webcomponents-icons/dist/search.js';
5-
import { Avatar, Icon, Input, ListItemStandard, ShellBarItem } from '../index';
6-
import { ShellBar } from './index';
3+
import menu2Icon from '@ui5/webcomponents-icons/dist/menu2.js';
4+
import navBackIcon from '@ui5/webcomponents-icons/dist/nav-back.js';
5+
import sysHelpIcon from '@ui5/webcomponents-icons/dist/sys-help.js';
6+
import { FlexBox } from '../../components/FlexBox/index.js';
7+
import { Button } from '../Button/index.js';
8+
import { Avatar, ShellBarItem, ShellBarSpacer } from '../index.js';
9+
import { Label } from '../Label/index.js';
10+
import { ShellBarSearch } from '../ShellBarSearch/index.js';
11+
import { Switch } from '../Switch/index.js';
12+
import { Tag } from '../Tag/index.js';
13+
import { Text } from '../Text/index.js';
14+
import { ShellBar } from './index.js';
715

816
const meta = {
917
title: 'Layouts & Floorplans / ShellBar',
@@ -17,30 +25,124 @@ const meta = {
1725
startButton: { control: { disable: true } },
1826
},
1927
args: {
28+
primaryTitle: 'Shell Bar',
29+
notificationsCount: '10',
30+
showNotifications: true,
2031
logo: <img src="https://sap.github.io/ui5-webcomponents/images/sap-logo-svg.svg" alt="SAP Logo" />,
2132
profile: (
2233
<Avatar>
23-
<img src={image} />
34+
<img src={image} alt="person-placeholder" />
2435
</Avatar>
2536
),
26-
menuItems: (
27-
<>
28-
<ListItemStandard data-key="1" text="Menu Item 1" />
29-
<ListItemStandard data-key="2" text="Menu Item 2" />
30-
<ListItemStandard data-key="3" text="Menu Item 3" />
31-
</>
32-
),
33-
searchField: <Input showClearIcon icon={<Icon name={searchIcon} />} />,
34-
notificationsCount: '10',
35-
primaryTitle: 'Shell Bar',
36-
secondaryTitle: 'Secondary Title',
37-
showNotifications: true,
38-
showProductSwitch: true,
39-
children: <ShellBarItem count="3" text={'ShellBarItem'} icon={addIcon} />,
37+
startButton: <Button icon={menu2Icon} tooltip="Menu" accessibleName="Menu" />,
38+
searchField: <ShellBarSearch showClearIcon placeholder="Search Apps, Products" />,
39+
children: <ShellBarItem text={'Help'} icon={sysHelpIcon} />,
4040
},
4141
tags: ['package:@ui5/webcomponents-fiori'],
4242
} satisfies Meta<typeof ShellBar>;
4343
export default meta;
4444
type Story = StoryObj<typeof meta>;
4545

4646
export const Default: Story = {};
47+
48+
export const AllFeatures: Story = {
49+
args: {
50+
showProductSwitch: true,
51+
startButton: (
52+
<>
53+
<Button icon={menu2Icon} tooltip="Menu" accessibleName="Menu" />
54+
<Button icon={navBackIcon} tooltip="Back" accessibleName="Back" />
55+
</>
56+
),
57+
content: (
58+
<>
59+
<Tag design="Set2" colorScheme="7">
60+
Trial
61+
</Tag>
62+
<Text>30 days remaining</Text>
63+
<ShellBarSpacer />
64+
<FlexBox gap="0 5px" alignItems="Center">
65+
<Switch />
66+
<Label>Try Beta Version</Label>
67+
</FlexBox>
68+
</>
69+
),
70+
},
71+
};
72+
73+
export const EmbeddedBackNavigation: Story = {
74+
args: {
75+
startButton: <Button icon={navBackIcon} tooltip="Back" accessibleName="Back" />,
76+
},
77+
};
78+
79+
export const TrialExample: Story = {
80+
args: {
81+
content: (
82+
<>
83+
<Tag design="Set2" colorScheme="7">
84+
Trial
85+
</Tag>
86+
<Text>30 days remaining</Text>
87+
</>
88+
),
89+
},
90+
};
91+
92+
export const ProductiveInstances: Story = {
93+
args: {
94+
content: (
95+
<Tag design="Set2" colorScheme="10">
96+
Region EMEA
97+
</Tag>
98+
),
99+
},
100+
101+
render(args) {
102+
return (
103+
<>
104+
<ShellBar {...args} />
105+
<ShellBar
106+
{...args}
107+
content={
108+
<Tag design="Set2" colorScheme="10">
109+
Region APJ
110+
</Tag>
111+
}
112+
/>
113+
</>
114+
);
115+
},
116+
};
117+
118+
export const NonProductiveInstances: Story = {
119+
args: {
120+
content: (
121+
<>
122+
<Tag design="Set2" colorScheme="8">
123+
Q System
124+
</Tag>
125+
<Text>Region EMEA</Text>
126+
</>
127+
),
128+
},
129+
130+
render(args) {
131+
return (
132+
<>
133+
<ShellBar {...args} />
134+
<ShellBar
135+
{...args}
136+
content={
137+
<>
138+
<Tag design="Set2" colorScheme="8">
139+
Q System
140+
</Tag>
141+
<Text>Region APJ</Text>
142+
</>
143+
}
144+
/>
145+
</>
146+
);
147+
},
148+
};

0 commit comments

Comments
 (0)