@axinom/mosaic-ui 0.75.0-rc.5 → 0.77.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/THIRD-PARTY-LICENSES.txt +1296 -0
- package/dist/cjs/components/ActionBar/ActionBar.d.ts +26 -0
- package/dist/cjs/components/ActionBar/ActionBar.d.ts.map +1 -0
- package/dist/cjs/components/ActionBar/ActionBar.model.d.ts +49 -0
- package/dist/cjs/components/ActionBar/ActionBar.model.d.ts.map +1 -0
- package/dist/cjs/components/ActionBar/ActionBarButton/ActionBarButton.d.ts +22 -0
- package/dist/cjs/components/ActionBar/ActionBarButton/ActionBarButton.d.ts.map +1 -0
- package/dist/cjs/components/ActionBar/helpers.d.ts +22 -0
- package/dist/cjs/components/ActionBar/helpers.d.ts.map +1 -0
- package/dist/cjs/components/ActionBar/index.d.ts +3 -0
- package/dist/cjs/components/ActionBar/index.d.ts.map +1 -0
- package/dist/cjs/components/Actions/Action/Action.d.ts.map +1 -1
- package/dist/cjs/components/ConfirmDialog/index.d.ts +1 -0
- package/dist/cjs/components/ConfirmDialog/index.d.ts.map +1 -1
- package/dist/cjs/components/ConfirmDialog/useConfirmableAction.d.ts +55 -0
- package/dist/cjs/components/ConfirmDialog/useConfirmableAction.d.ts.map +1 -0
- package/dist/cjs/components/Explorer/BulkEdit/useBulkEdit.d.ts.map +1 -1
- package/dist/cjs/components/Explorer/Explorer.d.ts.map +1 -1
- package/dist/cjs/components/Explorer/QuickEdit/useQuickEdit.d.ts +14 -3
- package/dist/cjs/components/Explorer/QuickEdit/useQuickEdit.d.ts.map +1 -1
- package/dist/cjs/components/Explorer/helpers/useActions.d.ts +15 -4
- package/dist/cjs/components/Explorer/helpers/useActions.d.ts.map +1 -1
- package/dist/cjs/components/Explorer/helpers/useSubtitle.d.ts.map +1 -1
- package/dist/cjs/components/List/List.d.ts +17 -3
- package/dist/cjs/components/List/List.d.ts.map +1 -1
- package/dist/cjs/components/List/List.model.d.ts +5 -1
- package/dist/cjs/components/List/List.model.d.ts.map +1 -1
- package/dist/cjs/components/List/ListHeader/ListHeader.d.ts +10 -1
- package/dist/cjs/components/List/ListHeader/ListHeader.d.ts.map +1 -1
- package/dist/cjs/components/List/ListRow/ListRow.d.ts +16 -5
- package/dist/cjs/components/List/ListRow/ListRow.d.ts.map +1 -1
- package/dist/cjs/components/List/ListRowRenderer/ListRowRenderer.d.ts.map +1 -1
- package/dist/cjs/components/List/helpers.d.ts +11 -3
- package/dist/cjs/components/List/helpers.d.ts.map +1 -1
- package/dist/cjs/components/List/useColumnsSize.d.ts +4 -2
- package/dist/cjs/components/List/useColumnsSize.d.ts.map +1 -1
- package/dist/cjs/components/PageHeader/PageHeader.d.ts +4 -1
- package/dist/cjs/components/PageHeader/PageHeader.d.ts.map +1 -1
- package/dist/cjs/components/PageHeader/PageHeader.model.d.ts +37 -1
- package/dist/cjs/components/PageHeader/PageHeader.model.d.ts.map +1 -1
- package/dist/cjs/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts +3 -0
- package/dist/cjs/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts.map +1 -1
- package/dist/cjs/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts +8 -0
- package/dist/cjs/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts.map +1 -1
- package/dist/cjs/components/PageHeader/helpers.d.ts +9 -0
- package/dist/cjs/components/PageHeader/helpers.d.ts.map +1 -0
- package/dist/cjs/components/index.d.ts +1 -0
- package/dist/cjs/components/index.d.ts.map +1 -1
- package/dist/cjs/hooks/index.d.ts +1 -0
- package/dist/cjs/hooks/index.d.ts.map +1 -1
- package/dist/cjs/hooks/useElementWidthObserver/useElementWidthObserver.d.ts.map +1 -0
- package/dist/cjs/index.js +4 -4
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/components/ActionBar/ActionBar.d.ts +26 -0
- package/dist/esm/components/ActionBar/ActionBar.d.ts.map +1 -0
- package/dist/esm/components/ActionBar/ActionBar.model.d.ts +49 -0
- package/dist/esm/components/ActionBar/ActionBar.model.d.ts.map +1 -0
- package/dist/esm/components/ActionBar/ActionBarButton/ActionBarButton.d.ts +22 -0
- package/dist/esm/components/ActionBar/ActionBarButton/ActionBarButton.d.ts.map +1 -0
- package/dist/esm/components/ActionBar/helpers.d.ts +22 -0
- package/dist/esm/components/ActionBar/helpers.d.ts.map +1 -0
- package/dist/esm/components/ActionBar/index.d.ts +3 -0
- package/dist/esm/components/ActionBar/index.d.ts.map +1 -0
- package/dist/esm/components/Actions/Action/Action.d.ts.map +1 -1
- package/dist/esm/components/ConfirmDialog/index.d.ts +1 -0
- package/dist/esm/components/ConfirmDialog/index.d.ts.map +1 -1
- package/dist/esm/components/ConfirmDialog/useConfirmableAction.d.ts +55 -0
- package/dist/esm/components/ConfirmDialog/useConfirmableAction.d.ts.map +1 -0
- package/dist/esm/components/Explorer/BulkEdit/useBulkEdit.d.ts.map +1 -1
- package/dist/esm/components/Explorer/Explorer.d.ts.map +1 -1
- package/dist/esm/components/Explorer/QuickEdit/useQuickEdit.d.ts +14 -3
- package/dist/esm/components/Explorer/QuickEdit/useQuickEdit.d.ts.map +1 -1
- package/dist/esm/components/Explorer/helpers/useActions.d.ts +15 -4
- package/dist/esm/components/Explorer/helpers/useActions.d.ts.map +1 -1
- package/dist/esm/components/Explorer/helpers/useSubtitle.d.ts.map +1 -1
- package/dist/esm/components/List/List.d.ts +17 -3
- package/dist/esm/components/List/List.d.ts.map +1 -1
- package/dist/esm/components/List/List.model.d.ts +5 -1
- package/dist/esm/components/List/List.model.d.ts.map +1 -1
- package/dist/esm/components/List/ListHeader/ListHeader.d.ts +10 -1
- package/dist/esm/components/List/ListHeader/ListHeader.d.ts.map +1 -1
- package/dist/esm/components/List/ListRow/ListRow.d.ts +16 -5
- package/dist/esm/components/List/ListRow/ListRow.d.ts.map +1 -1
- package/dist/esm/components/List/ListRowRenderer/ListRowRenderer.d.ts.map +1 -1
- package/dist/esm/components/List/helpers.d.ts +11 -3
- package/dist/esm/components/List/helpers.d.ts.map +1 -1
- package/dist/esm/components/List/useColumnsSize.d.ts +4 -2
- package/dist/esm/components/List/useColumnsSize.d.ts.map +1 -1
- package/dist/esm/components/PageHeader/PageHeader.d.ts +4 -1
- package/dist/esm/components/PageHeader/PageHeader.d.ts.map +1 -1
- package/dist/esm/components/PageHeader/PageHeader.model.d.ts +37 -1
- package/dist/esm/components/PageHeader/PageHeader.model.d.ts.map +1 -1
- package/dist/esm/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts +3 -0
- package/dist/esm/components/PageHeader/PageHeaderAction/PageHeaderAction.d.ts.map +1 -1
- package/dist/esm/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts +8 -0
- package/dist/esm/components/PageHeader/PageHeaderAction/PageHeaderAction.model.d.ts.map +1 -1
- package/dist/esm/components/PageHeader/helpers.d.ts +9 -0
- package/dist/esm/components/PageHeader/helpers.d.ts.map +1 -0
- package/dist/esm/components/index.d.ts +1 -0
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/hooks/index.d.ts +1 -0
- package/dist/esm/hooks/index.d.ts.map +1 -1
- package/dist/esm/hooks/useElementWidthObserver/useElementWidthObserver.d.ts.map +1 -0
- package/dist/esm/index.js +4 -4
- package/dist/esm/index.js.map +1 -1
- package/package.json +7 -3
- package/src/components/ActionBar/ActionBar.model.ts +61 -0
- package/src/components/ActionBar/ActionBar.module.scss +64 -0
- package/src/components/ActionBar/ActionBar.spec.tsx +398 -0
- package/src/components/ActionBar/ActionBar.stories.tsx +205 -0
- package/src/components/ActionBar/ActionBar.tsx +170 -0
- package/src/components/ActionBar/ActionBarButton/ActionBarButton.module.scss +140 -0
- package/src/components/ActionBar/ActionBarButton/ActionBarButton.tsx +193 -0
- package/src/components/ActionBar/helpers.spec.ts +41 -0
- package/src/components/ActionBar/helpers.ts +54 -0
- package/src/components/ActionBar/index.ts +2 -0
- package/src/components/Actions/Action/Action.spec.tsx +64 -2
- package/src/components/Actions/Action/Action.tsx +6 -1
- package/src/components/ConfirmDialog/index.ts +1 -0
- package/src/components/ConfirmDialog/useConfirmableAction.tsx +159 -0
- package/src/components/EmptyStation/EmptyStation.stories.tsx +97 -0
- package/src/components/Explorer/BulkEdit/useBulkEdit.tsx +2 -0
- package/src/components/Explorer/Explorer.spec.tsx +97 -8
- package/src/components/Explorer/Explorer.tsx +26 -13
- package/src/components/Explorer/NavigationExplorer/NavigationExplorer.stories.tsx +124 -1
- package/src/components/Explorer/QuickEdit/useQuickEdit.spec.tsx +94 -50
- package/src/components/Explorer/QuickEdit/useQuickEdit.tsx +101 -42
- package/src/components/Explorer/SelectionExplorer/SelectionExplorer.spec.tsx +46 -13
- package/src/components/Explorer/helpers/useActions.ts +125 -73
- package/src/components/Explorer/helpers/useSubtitle.spec.tsx +33 -23
- package/src/components/Explorer/helpers/useSubtitle.tsx +18 -26
- package/src/components/List/List.model.ts +5 -1
- package/src/components/List/List.module.scss +25 -6
- package/src/components/List/List.spec.tsx +498 -1
- package/src/components/List/List.stories.tsx +137 -8
- package/src/components/List/List.tsx +305 -194
- package/src/components/List/ListHeader/ListHeader.module.scss +14 -0
- package/src/components/List/ListHeader/ListHeader.spec.tsx +1 -0
- package/src/components/List/ListHeader/ListHeader.tsx +25 -8
- package/src/components/List/ListRow/ListRow.module.scss +1 -1
- package/src/components/List/ListRow/ListRow.spec.tsx +109 -22
- package/src/components/List/ListRow/ListRow.tsx +52 -13
- package/src/components/List/ListRowRenderer/ListRowRenderer.tsx +28 -22
- package/src/components/List/helpers.spec.ts +29 -0
- package/src/components/List/helpers.ts +17 -9
- package/src/components/List/useColumnsSize.ts +17 -7
- package/src/components/PageHeader/PageHeader.model.ts +38 -1
- package/src/components/PageHeader/PageHeader.module.scss +39 -18
- package/src/components/PageHeader/PageHeader.spec.tsx +407 -18
- package/src/components/PageHeader/PageHeader.stories.tsx +95 -12
- package/src/components/PageHeader/PageHeader.tsx +89 -38
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.model.ts +8 -0
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.module.scss +50 -42
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.spec.tsx +193 -1
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.stories.tsx +36 -0
- package/src/components/PageHeader/PageHeaderAction/PageHeaderAction.tsx +81 -130
- package/src/components/PageHeader/helpers.spec.ts +60 -0
- package/src/components/PageHeader/helpers.ts +36 -0
- package/src/components/index.ts +1 -0
- package/src/hooks/index.ts +1 -0
- package/src/styles/variables.scss +41 -7
- package/dist/cjs/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.d.ts +0 -35
- package/dist/cjs/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.d.ts.map +0 -1
- package/dist/cjs/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContext.d.ts +0 -6
- package/dist/cjs/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContext.d.ts.map +0 -1
- package/dist/cjs/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContextProvider.d.ts +0 -3
- package/dist/cjs/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContextProvider.d.ts.map +0 -1
- package/dist/cjs/components/PageHeader/helpers/useElementWidthObserver.d.ts.map +0 -1
- package/dist/esm/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.d.ts +0 -35
- package/dist/esm/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.d.ts.map +0 -1
- package/dist/esm/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContext.d.ts +0 -6
- package/dist/esm/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContext.d.ts.map +0 -1
- package/dist/esm/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContextProvider.d.ts +0 -3
- package/dist/esm/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContextProvider.d.ts.map +0 -1
- package/dist/esm/components/PageHeader/helpers/useElementWidthObserver.d.ts.map +0 -1
- package/src/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.module.scss +0 -77
- package/src/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.spec.tsx +0 -122
- package/src/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroup.tsx +0 -235
- package/src/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContext.ts +0 -15
- package/src/components/PageHeader/PageHeaderActionsGroup/PageHeaderActionsGroupsContextProvider.tsx +0 -37
- /package/dist/cjs/{components/PageHeader/helpers → hooks/useElementWidthObserver}/useElementWidthObserver.d.ts +0 -0
- /package/dist/esm/{components/PageHeader/helpers → hooks/useElementWidthObserver}/useElementWidthObserver.d.ts +0 -0
- /package/src/{components/PageHeader/helpers → hooks/useElementWidthObserver}/useElementWidthObserver.tsx +0 -0
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import React from 'react';
|
|
3
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
2
4
|
import { action } from 'storybook/actions';
|
|
3
5
|
import { IconName } from '../Icons';
|
|
4
6
|
import { PageHeader } from './PageHeader';
|
|
@@ -78,9 +80,30 @@ const bulkHeaderActions: PageHeaderActionProps[] = [
|
|
|
78
80
|
},
|
|
79
81
|
];
|
|
80
82
|
|
|
83
|
+
const exportHeaderActions: PageHeaderActionProps[] = [
|
|
84
|
+
{
|
|
85
|
+
label: 'Export as CSV',
|
|
86
|
+
icon: IconName.File,
|
|
87
|
+
onClick: action('onActionSelected'),
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
label: 'Export Settings',
|
|
91
|
+
path: '/export-settings',
|
|
92
|
+
tag: 'NEW',
|
|
93
|
+
},
|
|
94
|
+
];
|
|
95
|
+
|
|
81
96
|
const meta: Meta<typeof PageHeader> = {
|
|
82
97
|
component: PageHeader,
|
|
83
98
|
title: 'Other Components/PageHeader',
|
|
99
|
+
decorators: [
|
|
100
|
+
// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
|
|
101
|
+
(Story) => (
|
|
102
|
+
<MemoryRouter>
|
|
103
|
+
<Story />
|
|
104
|
+
</MemoryRouter>
|
|
105
|
+
),
|
|
106
|
+
],
|
|
84
107
|
};
|
|
85
108
|
export default meta;
|
|
86
109
|
|
|
@@ -97,11 +120,22 @@ export const Titles: StoryObj<typeof PageHeader> = {
|
|
|
97
120
|
args: { title: 'Title', subtitle: 'Subtitle' },
|
|
98
121
|
};
|
|
99
122
|
|
|
123
|
+
export const TitleOnly: StoryObj<typeof PageHeader> = {
|
|
124
|
+
parameters: {
|
|
125
|
+
docs: {
|
|
126
|
+
description: {
|
|
127
|
+
story: 'Without a subtitle, the title is centered vertically.',
|
|
128
|
+
},
|
|
129
|
+
},
|
|
130
|
+
},
|
|
131
|
+
args: { title: 'Episodes' },
|
|
132
|
+
};
|
|
133
|
+
|
|
100
134
|
export const Actions: StoryObj<typeof PageHeader> = {
|
|
101
135
|
parameters: {
|
|
102
136
|
docs: {
|
|
103
137
|
description: {
|
|
104
|
-
story:
|
|
138
|
+
story: `An array of standard page header actions can be passed in. An action shows its icon, and its label as a tooltip.`,
|
|
105
139
|
},
|
|
106
140
|
},
|
|
107
141
|
},
|
|
@@ -112,12 +146,59 @@ export const Actions: StoryObj<typeof PageHeader> = {
|
|
|
112
146
|
},
|
|
113
147
|
};
|
|
114
148
|
|
|
149
|
+
export const ActionsWithoutIcons: StoryObj<typeof PageHeader> = {
|
|
150
|
+
parameters: {
|
|
151
|
+
docs: {
|
|
152
|
+
description: {
|
|
153
|
+
story: `An action without an icon shows its label instead, which is cut after four lines.
|
|
154
|
+
Spacers separate groups of actions.`,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
args: {
|
|
159
|
+
title: 'Episodes',
|
|
160
|
+
actions: [
|
|
161
|
+
{
|
|
162
|
+
label: 'Create Snapshot',
|
|
163
|
+
kind: 'action',
|
|
164
|
+
onClick: action('onActionSelected'),
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
label: 'Create Snapshot and Publish all Episodes',
|
|
168
|
+
kind: 'action',
|
|
169
|
+
onClick: action('onActionSelected'),
|
|
170
|
+
},
|
|
171
|
+
{ kind: 'spacer' },
|
|
172
|
+
{
|
|
173
|
+
label: 'Bulk Actions',
|
|
174
|
+
icon: IconName.Bulk,
|
|
175
|
+
kind: 'group',
|
|
176
|
+
actions: bulkHeaderActions,
|
|
177
|
+
},
|
|
178
|
+
{ kind: 'spacer' },
|
|
179
|
+
{
|
|
180
|
+
label: 'Quick View',
|
|
181
|
+
icon: IconName.QuickEdit,
|
|
182
|
+
kind: 'action',
|
|
183
|
+
onClick: action('onActionSelected'),
|
|
184
|
+
},
|
|
185
|
+
{ kind: 'spacer' },
|
|
186
|
+
{
|
|
187
|
+
label: 'New',
|
|
188
|
+
icon: IconName.Plus,
|
|
189
|
+
kind: 'action',
|
|
190
|
+
path: '/new',
|
|
191
|
+
},
|
|
192
|
+
],
|
|
193
|
+
},
|
|
194
|
+
};
|
|
195
|
+
|
|
115
196
|
export const ActionsGroup: StoryObj<typeof PageHeader> = {
|
|
116
197
|
parameters: {
|
|
117
198
|
docs: {
|
|
118
199
|
description: {
|
|
119
|
-
story: `
|
|
120
|
-
|
|
200
|
+
story: `An actions group renders a single action on the page header. Clicking it opens an action bar below the page header, holding the actions of the group, and clicking it again closes the bar.
|
|
201
|
+
The bar can show a label of its own through 'actionBarLabel'. Actions that do not fit the available width move into an overflow menu.`,
|
|
121
202
|
},
|
|
122
203
|
},
|
|
123
204
|
},
|
|
@@ -130,6 +211,8 @@ export const ActionsGroup: StoryObj<typeof PageHeader> = {
|
|
|
130
211
|
icon: IconName.Bulk,
|
|
131
212
|
kind: 'group',
|
|
132
213
|
actions: bulkHeaderActions,
|
|
214
|
+
actionBarLabel: 'Selected 3',
|
|
215
|
+
openActionsGroupOnStart: true,
|
|
133
216
|
},
|
|
134
217
|
],
|
|
135
218
|
},
|
|
@@ -140,8 +223,8 @@ export const All: StoryObj<typeof PageHeader> = {
|
|
|
140
223
|
parameters: {
|
|
141
224
|
docs: {
|
|
142
225
|
description: {
|
|
143
|
-
story:
|
|
144
|
-
|
|
226
|
+
story: `When actions and bulk actions are present, a spacer will be created in-between to help differentiate them.
|
|
227
|
+
Only one actions group can be open at a time, so opening a group closes the one that is open. Groups can hold navigation actions as well.`,
|
|
145
228
|
},
|
|
146
229
|
},
|
|
147
230
|
},
|
|
@@ -156,17 +239,17 @@ export const All: StoryObj<typeof PageHeader> = {
|
|
|
156
239
|
icon: IconName.Bulk,
|
|
157
240
|
kind: 'group',
|
|
158
241
|
actions: bulkHeaderActions,
|
|
159
|
-
onActionsGroupToggled: async (): Promise<void> => {
|
|
160
|
-
action('
|
|
242
|
+
onActionsGroupToggled: async (expanded: boolean): Promise<void> => {
|
|
243
|
+
action('onBulkActionsToggled')(expanded);
|
|
161
244
|
},
|
|
162
245
|
},
|
|
163
246
|
{
|
|
164
|
-
label: '
|
|
165
|
-
icon: IconName.
|
|
247
|
+
label: 'Export',
|
|
248
|
+
icon: IconName.File,
|
|
166
249
|
kind: 'group',
|
|
167
|
-
actions:
|
|
168
|
-
onActionsGroupToggled: async (): Promise<void> => {
|
|
169
|
-
action('
|
|
250
|
+
actions: exportHeaderActions,
|
|
251
|
+
onActionsGroupToggled: async (expanded: boolean): Promise<void> => {
|
|
252
|
+
action('onExportToggled')(expanded);
|
|
170
253
|
},
|
|
171
254
|
},
|
|
172
255
|
],
|
|
@@ -1,23 +1,37 @@
|
|
|
1
1
|
import clsx from 'clsx';
|
|
2
|
-
import React, {
|
|
2
|
+
import React, { useState } from 'react';
|
|
3
3
|
import { useTabTitle } from '../../hooks/useTabTitle/useTabTitle';
|
|
4
|
-
import
|
|
4
|
+
import { ActionBar } from '../ActionBar';
|
|
5
|
+
import type {
|
|
6
|
+
PageHeaderActionItemProps,
|
|
7
|
+
PageHeaderProps,
|
|
8
|
+
} from './PageHeader.model';
|
|
5
9
|
import classes from './PageHeader.module.scss';
|
|
6
10
|
import type { PageHeaderActionProps } from './PageHeaderAction';
|
|
7
11
|
import { PageHeaderAction } from './PageHeaderAction/PageHeaderAction';
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
import { toActionBarAction } from './helpers';
|
|
13
|
+
|
|
14
|
+
type PageHeaderActionsGroupItem = Extract<
|
|
15
|
+
PageHeaderActionItemProps,
|
|
16
|
+
{ kind: 'group' }
|
|
17
|
+
>;
|
|
18
|
+
|
|
19
|
+
const isActionsGroup = (
|
|
20
|
+
action: PageHeaderActionItemProps,
|
|
21
|
+
): action is PageHeaderActionsGroupItem => action.kind === 'group';
|
|
11
22
|
|
|
12
23
|
/**
|
|
13
24
|
* Primary header for stations. Accepts a title, subtitle, actions, and actions groups.
|
|
25
|
+
*
|
|
26
|
+
* An actions group renders a single action, which opens an action bar holding
|
|
27
|
+
* the actions of the group below the header. Only one group can be open at a time.
|
|
14
28
|
* @example
|
|
15
29
|
* <PageHeader title="title" subtitle="subtitle" actions={[
|
|
16
30
|
* { label: 'Undo', icon: IconName.Undo, kind: 'action', onClick: onActionSelected },
|
|
17
31
|
* { label: 'Cancel', icon: IconName.X, kind: 'action' onClick: onActionSelected },
|
|
18
32
|
* { kind: 'spacer' },
|
|
19
33
|
* { label: 'Actions Group', kind: 'group', actions: [
|
|
20
|
-
* { label: 'Action 1',
|
|
34
|
+
* { label: 'Action 1', icon: IconName.Delete, confirmationMode: 'Advanced', onClick: onActionSelected },
|
|
21
35
|
* ]}
|
|
22
36
|
* ]} />
|
|
23
37
|
*/
|
|
@@ -29,23 +43,46 @@ export const PageHeader: React.FC<PageHeaderProps> = ({
|
|
|
29
43
|
setTabTitle = true,
|
|
30
44
|
}) => {
|
|
31
45
|
useTabTitle(title, setTabTitle);
|
|
32
|
-
const { width, ref } = useElementWidthObserver<HTMLDivElement>();
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Label of the open group, or `null` once the groups were closed. Stays
|
|
49
|
+
* `undefined` until a group is toggled, in which case a group asking to be
|
|
50
|
+
* open on start is the open one.
|
|
51
|
+
*/
|
|
52
|
+
const [toggledGroupLabel, setToggledGroupLabel] = useState<string | null>();
|
|
53
|
+
|
|
54
|
+
const groups = actions.filter(isActionsGroup);
|
|
55
|
+
|
|
56
|
+
const openGroup =
|
|
57
|
+
toggledGroupLabel === undefined
|
|
58
|
+
? groups.find((group) => group.openActionsGroupOnStart)
|
|
59
|
+
: groups.find((group) => group.label === toggledGroupLabel);
|
|
60
|
+
|
|
61
|
+
const toggleGroup = async (
|
|
62
|
+
group: PageHeaderActionsGroupItem,
|
|
63
|
+
): Promise<void> => {
|
|
64
|
+
const isOpening = group !== openGroup;
|
|
65
|
+
|
|
66
|
+
try {
|
|
67
|
+
// Only one group can be open, so the open one is closed first.
|
|
68
|
+
if (isOpening && openGroup !== undefined) {
|
|
69
|
+
await openGroup.onActionsGroupToggled?.(false);
|
|
70
|
+
setToggledGroupLabel(null);
|
|
71
|
+
}
|
|
35
72
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
73
|
+
await group.onActionsGroupToggled?.(isOpening);
|
|
74
|
+
} catch {
|
|
75
|
+
// A handler rejecting aborts the toggle.
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
39
78
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
}, [width, actions.length]);
|
|
79
|
+
setToggledGroupLabel(isOpening ? group.label : null);
|
|
80
|
+
};
|
|
43
81
|
|
|
44
82
|
return (
|
|
45
83
|
<div
|
|
46
84
|
className={clsx(classes.container, 'page-header-container', className)}
|
|
47
85
|
data-test-id="page-header"
|
|
48
|
-
ref={ref}
|
|
49
86
|
>
|
|
50
87
|
<div className={clsx(classes.titles)}>
|
|
51
88
|
<div
|
|
@@ -64,30 +101,44 @@ export const PageHeader: React.FC<PageHeaderProps> = ({
|
|
|
64
101
|
</div>
|
|
65
102
|
</div>
|
|
66
103
|
<div className={classes.actions} data-test-id="page-header-actions">
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
104
|
+
{actions.map((action, index) => {
|
|
105
|
+
switch (action.kind) {
|
|
106
|
+
case 'group':
|
|
107
|
+
return (
|
|
108
|
+
<PageHeaderAction
|
|
109
|
+
key={index}
|
|
110
|
+
label={action.label}
|
|
111
|
+
icon={action.icon}
|
|
112
|
+
disabled={action.disabled}
|
|
113
|
+
className={action.className}
|
|
114
|
+
toggled={action === openGroup}
|
|
115
|
+
onClick={() => toggleGroup(action)}
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
case 'spacer':
|
|
119
|
+
return <div key={index} className={classes.spacer} />;
|
|
120
|
+
case 'action':
|
|
121
|
+
return (
|
|
122
|
+
<PageHeaderAction
|
|
123
|
+
key={index}
|
|
124
|
+
{...(action as PageHeaderActionProps)}
|
|
125
|
+
/>
|
|
126
|
+
);
|
|
127
|
+
}
|
|
128
|
+
})}
|
|
90
129
|
</div>
|
|
130
|
+
{openGroup !== undefined && (
|
|
131
|
+
<ActionBar
|
|
132
|
+
// Each group gets a bar of its own, even if they hold the same actions.
|
|
133
|
+
key={openGroup.label}
|
|
134
|
+
className={classes.actionBar}
|
|
135
|
+
label={openGroup.actionBarLabel}
|
|
136
|
+
actions={openGroup.actions.map((action) => ({
|
|
137
|
+
...toActionBarAction(action),
|
|
138
|
+
disabled: openGroup.groupActionsDisabled || action.disabled,
|
|
139
|
+
}))}
|
|
140
|
+
/>
|
|
141
|
+
)}
|
|
91
142
|
</div>
|
|
92
143
|
);
|
|
93
144
|
};
|
|
@@ -22,6 +22,14 @@ export interface PageHeaderJsActionProps
|
|
|
22
22
|
* Changes the background color to the corresponding action type. (default: 'Context')
|
|
23
23
|
*/
|
|
24
24
|
actionType?: PageHeaderActionType;
|
|
25
|
+
/**
|
|
26
|
+
* Whether the action is toggled on. When `true`, the action renders in its
|
|
27
|
+
* toggled (pressed) state and `actionType` is ignored. When `false` or
|
|
28
|
+
* omitted, the action renders according to `actionType`.
|
|
29
|
+
* Set this to make the action a toggle button rather than a one-shot action.
|
|
30
|
+
* (default: undefined)
|
|
31
|
+
*/
|
|
32
|
+
toggled?: boolean;
|
|
25
33
|
}
|
|
26
34
|
|
|
27
35
|
export interface PageHeaderNavigationActionProps
|
|
@@ -6,11 +6,15 @@
|
|
|
6
6
|
@include boxSizing;
|
|
7
7
|
|
|
8
8
|
height: $page-header-height;
|
|
9
|
-
width:
|
|
9
|
+
width: var(--page-header-action-width, $page-header-action-width);
|
|
10
|
+
|
|
11
|
+
// Holds either the icon or the label, centered. The hidden label and the tag
|
|
12
|
+
// are laid over the action.
|
|
13
|
+
position: relative;
|
|
14
|
+
overflow: hidden;
|
|
10
15
|
|
|
11
16
|
display: grid;
|
|
12
|
-
|
|
13
|
-
grid-template-rows: 1fr 1fr;
|
|
17
|
+
place-items: center;
|
|
14
18
|
|
|
15
19
|
color: var(--page-header-action-color, $page-header-action-color);
|
|
16
20
|
background-color: var(
|
|
@@ -20,30 +24,52 @@
|
|
|
20
24
|
cursor: pointer;
|
|
21
25
|
user-select: none;
|
|
22
26
|
|
|
23
|
-
.label,
|
|
24
|
-
.icon {
|
|
25
|
-
display: grid;
|
|
26
|
-
grid-template: 1fr / 1fr;
|
|
27
|
-
place-items: center;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
27
|
.label {
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
28
|
+
// Long labels wrap onto further rows and are cut after the fourth one. The
|
|
29
|
+
// wrapping is set explicitly, as `all: unset` would inherit a `nowrap` of
|
|
30
|
+
// whatever the header is rendered in.
|
|
31
|
+
display: -webkit-box;
|
|
32
|
+
-webkit-box-orient: vertical;
|
|
33
|
+
-webkit-line-clamp: 4;
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
white-space: normal;
|
|
36
|
+
overflow-wrap: anywhere;
|
|
34
37
|
|
|
35
|
-
|
|
38
|
+
// Chrome centers the cut row without its ellipsis, and appends the
|
|
39
|
+
// ellipsis after it, which can then reach up to half its width past the
|
|
40
|
+
// row. The padding leaves room for it, as overflow is only cut at the edge
|
|
41
|
+
// of the padding.
|
|
42
|
+
width: 100%;
|
|
43
|
+
padding: 0 6px;
|
|
44
|
+
|
|
45
|
+
font-size: var(
|
|
46
|
+
--page-header-action-font-size,
|
|
47
|
+
$page-header-action-font-size
|
|
48
|
+
);
|
|
36
49
|
line-height: 1.1;
|
|
37
50
|
text-align: center;
|
|
38
51
|
}
|
|
39
52
|
|
|
53
|
+
// Transparent rather than removed, so that it still names the action and
|
|
54
|
+
// takes the clicks on it, e.g. of tests that find an action by its label.
|
|
55
|
+
.hiddenLabel {
|
|
56
|
+
position: absolute;
|
|
57
|
+
inset: 0;
|
|
58
|
+
|
|
59
|
+
opacity: 0;
|
|
60
|
+
}
|
|
61
|
+
|
|
40
62
|
.icon {
|
|
41
|
-
|
|
42
|
-
|
|
63
|
+
display: grid;
|
|
64
|
+
place-items: center;
|
|
43
65
|
}
|
|
44
66
|
|
|
45
67
|
.icon > * {
|
|
46
|
-
height:
|
|
68
|
+
height: var(--page-header-action-icon-size, $page-header-action-icon-size);
|
|
69
|
+
max-width: var(
|
|
70
|
+
--page-header-action-icon-size,
|
|
71
|
+
$page-header-action-icon-size
|
|
72
|
+
);
|
|
47
73
|
}
|
|
48
74
|
|
|
49
75
|
&:hover {
|
|
@@ -118,23 +144,10 @@
|
|
|
118
144
|
}
|
|
119
145
|
|
|
120
146
|
&:hover {
|
|
121
|
-
color: var(--page-header-action-color, $page-header-action-color);
|
|
122
|
-
|
|
123
147
|
background-color: var(
|
|
124
|
-
--page-header-action-
|
|
125
|
-
$page-header-action-
|
|
148
|
+
--page-header-action-active-hover-background-color,
|
|
149
|
+
$page-header-action-active-hover-background-color
|
|
126
150
|
);
|
|
127
|
-
|
|
128
|
-
.pageHeaderActionsIcons {
|
|
129
|
-
polygon,
|
|
130
|
-
path,
|
|
131
|
-
circle {
|
|
132
|
-
stroke: var(
|
|
133
|
-
--page-header-action-icon-color,
|
|
134
|
-
$page-header-action-icon-color
|
|
135
|
-
);
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
151
|
}
|
|
139
152
|
}
|
|
140
153
|
|
|
@@ -164,12 +177,12 @@
|
|
|
164
177
|
color: var(--actions-disabled-fg-color, $actions-disabled-fg-color);
|
|
165
178
|
}
|
|
166
179
|
|
|
180
|
+
// A ribbon across the top right corner of the action.
|
|
167
181
|
.tag {
|
|
168
182
|
position: absolute;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
left: 0;
|
|
183
|
+
top: 6px;
|
|
184
|
+
right: -22px;
|
|
185
|
+
transform: rotate(45deg);
|
|
173
186
|
display: grid;
|
|
174
187
|
background-color: var(
|
|
175
188
|
--page-header-action-tag-background-color,
|
|
@@ -180,15 +193,10 @@
|
|
|
180
193
|
$page-header-action-tag-font-size
|
|
181
194
|
);
|
|
182
195
|
font-weight: bold;
|
|
183
|
-
width:
|
|
196
|
+
width: 70px;
|
|
184
197
|
height: 14px;
|
|
185
198
|
align-items: center;
|
|
186
199
|
text-align: center;
|
|
187
200
|
z-index: 0;
|
|
188
201
|
}
|
|
189
|
-
|
|
190
|
-
&:has(.tag) {
|
|
191
|
-
position: relative;
|
|
192
|
-
overflow: hidden;
|
|
193
|
-
}
|
|
194
202
|
}
|