@covalent/components 0.0.0-COVALENT
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/.babelrc +10 -0
- package/.eslintrc.json +18 -0
- package/.storybook/main.js +34 -0
- package/.storybook/manager-head.html +62 -0
- package/.storybook/manager.js +1 -0
- package/.storybook/preview-head.html +20 -0
- package/.storybook/preview.js +20 -0
- package/README.md +179 -0
- package/component-config.json +313 -0
- package/index.html +288 -0
- package/jest.config.js +18 -0
- package/package.json +315 -0
- package/project.json +104 -0
- package/public/index.scss +1 -0
- package/public/reset.css +128 -0
- package/src/action-ribbon/_action-ribbon.theme.scss +90 -0
- package/src/action-ribbon/action-ribbon-base.ts +164 -0
- package/src/action-ribbon/action-ribbon.scss +20 -0
- package/src/action-ribbon/action-ribbon.spec.ts +11 -0
- package/src/action-ribbon/action-ribbon.stories.js +78 -0
- package/src/action-ribbon/action-ribbon.ts +26 -0
- package/src/alert/_alert.theme.scss +116 -0
- package/src/alert/alert-base.ts +175 -0
- package/src/alert/alert.scss +55 -0
- package/src/alert/alert.spec.ts +26 -0
- package/src/alert/alert.stories.js +76 -0
- package/src/alert/alert.ts +26 -0
- package/src/app-shell/app-shell.scss +387 -0
- package/src/app-shell/app-shell.stories.js +323 -0
- package/src/app-shell/app-shell.ts +388 -0
- package/src/badge/badge.scss +60 -0
- package/src/badge/badge.spec.ts +40 -0
- package/src/badge/badge.stories.js +88 -0
- package/src/badge/badge.ts +122 -0
- package/src/button/Overview.mdx +160 -0
- package/src/button/button.scss +28 -0
- package/src/button/button.spec.ts +11 -0
- package/src/button/button.stories.js +102 -0
- package/src/button/button.ts +17 -0
- package/src/card/card-base.ts +69 -0
- package/src/card/card.scss +45 -0
- package/src/card/card.spec.ts +11 -0
- package/src/card/card.ts +21 -0
- package/src/card/cards.stories.js +40 -0
- package/src/checkbox/checkbox.scss +8 -0
- package/src/checkbox/checkbox.spec.ts +11 -0
- package/src/checkbox/checkbox.stories.js +61 -0
- package/src/checkbox/checkbox.ts +18 -0
- package/src/chips/chip-base.ts +276 -0
- package/src/chips/chip-set-base.ts +184 -0
- package/src/chips/chip-set.scss +15 -0
- package/src/chips/chip-set.spec.ts +11 -0
- package/src/chips/chip-set.ts +27 -0
- package/src/chips/chip.scss +40 -0
- package/src/chips/chip.spec.ts +11 -0
- package/src/chips/chip.ts +26 -0
- package/src/chips/chips.stories.js +81 -0
- package/src/circular-progress/circular-progress.spec.ts +11 -0
- package/src/circular-progress/circular-progress.stories.js +40 -0
- package/src/circular-progress/circular-progress.ts +16 -0
- package/src/code-editor/code-editor.scss +20 -0
- package/src/code-editor/code-editor.spec.ts +11 -0
- package/src/code-editor/code-editor.stories.js +44 -0
- package/src/code-editor/code-editor.theme.ts +199 -0
- package/src/code-editor/code-editor.ts +231 -0
- package/src/code-snippet/code-snippet.scss +126 -0
- package/src/code-snippet/code-snippet.spec.ts +11 -0
- package/src/code-snippet/code-snippet.stories.js +134 -0
- package/src/code-snippet/code-snippet.ts +93 -0
- package/src/data-table/_data-table.theme.scss +39 -0
- package/src/data-table/data-table.stories.js +24 -0
- package/src/data-table/data-table.stories.scss +11 -0
- package/src/dialog/Overview.mdx +39 -0
- package/src/dialog/dialog.scss +17 -0
- package/src/dialog/dialog.spec.ts +11 -0
- package/src/dialog/dialog.stories.js +89 -0
- package/src/dialog/dialog.ts +44 -0
- package/src/drawer/drawer.scss +4 -0
- package/src/drawer/drawer.spec.ts +11 -0
- package/src/drawer/drawer.ts +18 -0
- package/src/empty-state/_empty-state.theme.scss +0 -0
- package/src/empty-state/empty-state.scss +67 -0
- package/src/empty-state/empty-state.spec.ts +11 -0
- package/src/empty-state/empty-state.stories.js +117 -0
- package/src/empty-state/empty-state.ts +61 -0
- package/src/expansion-panel/Overview.mdx +108 -0
- package/src/expansion-panel/expansion-panel-incorrect-example.png +0 -0
- package/src/expansion-panel/expansion-panel-item.scss +243 -0
- package/src/expansion-panel/expansion-panel-item.ts +95 -0
- package/src/expansion-panel/expansion-panel.spec.ts +11 -0
- package/src/expansion-panel/expansion-panel.stories.js +76 -0
- package/src/expansion-panel/expansion-panel.ts +94 -0
- package/src/focused-page/focused-page.scss +113 -0
- package/src/focused-page/focused-page.spec.ts +11 -0
- package/src/focused-page/focused-page.stories.js +167 -0
- package/src/focused-page/focused-page.ts +201 -0
- package/src/formfield/formfield.scss +8 -0
- package/src/formfield/formfield.spec.ts +11 -0
- package/src/formfield/formfield.ts +24 -0
- package/src/full-screen-dialog/full-screen-dialog.scss +37 -0
- package/src/full-screen-dialog/full-screen-dialog.spec.ts +11 -0
- package/src/full-screen-dialog/full-screen-dialog.stories.js +172 -0
- package/src/full-screen-dialog/full-screen-dialog.ts +84 -0
- package/src/icon/_icon-list.ts +316 -0
- package/src/icon/icon-demo.scss +25 -0
- package/src/icon/icon-demo.ts +37 -0
- package/src/icon/icon.spec.ts +11 -0
- package/src/icon/icon.stories.js +55 -0
- package/src/icon/icon.ts +16 -0
- package/src/icon-button/_icon-button.theme.scss +9 -0
- package/src/icon-button/icon-button.scss +12 -0
- package/src/icon-button/icon-button.spec.ts +11 -0
- package/src/icon-button/icon-button.stories.js +24 -0
- package/src/icon-button/icon-button.ts +19 -0
- package/src/icon-button-toggle/icon-button-toggle.scss +19 -0
- package/src/icon-button-toggle/icon-button-toggle.spec.ts +11 -0
- package/src/icon-button-toggle/icon-button-toggle.stories.js +32 -0
- package/src/icon-button-toggle/icon-button-toggle.ts +50 -0
- package/src/icon-checkbox/icon-check-toggle.ts +64 -0
- package/src/icon-checkbox/icon-check.spec.ts +11 -0
- package/src/icon-checkbox/icon-checkbox.scss +95 -0
- package/src/icon-checkbox/icon-checkbox.stories.js +77 -0
- package/src/icon-lockup/icon-lockup.scss +47 -0
- package/src/icon-lockup/icon-lockup.spec.ts +11 -0
- package/src/icon-lockup/icon-lockup.stories.js +93 -0
- package/src/icon-lockup/icon-lockup.ts +125 -0
- package/src/icon-radio/icon-radio-toggle.ts +43 -0
- package/src/icon-radio/icon-radio.scss +63 -0
- package/src/icon-radio/icon-radio.spec.ts +11 -0
- package/src/icon-radio/icon-radio.stories.js +23 -0
- package/src/index.scss +1 -0
- package/src/index.ts +57 -0
- package/src/linear-progress/linear-progress.scss +4 -0
- package/src/linear-progress/linear-progress.spec.ts +11 -0
- package/src/linear-progress/linear-progress.stories.js +43 -0
- package/src/linear-progress/linear-progress.ts +18 -0
- package/src/list/Overview.mdx +91 -0
- package/src/list/_list.theme.scss +100 -0
- package/src/list/check-list-item.spec.ts +11 -0
- package/src/list/check-list-item.ts +25 -0
- package/src/list/list-item.scss +56 -0
- package/src/list/list-item.spec.ts +11 -0
- package/src/list/list-item.ts +31 -0
- package/src/list/list.scss +25 -0
- package/src/list/list.stories.js +120 -0
- package/src/list/list.ts +23 -0
- package/src/list/nav-list-item.scss +159 -0
- package/src/list/nav-list-item.ts +223 -0
- package/src/list/radio-list-item.ts +25 -0
- package/src/menu/menu.scss +3 -0
- package/src/menu/menu.spec.ts +11 -0
- package/src/menu/menu.stories.js +110 -0
- package/src/menu/menu.ts +23 -0
- package/src/notebook-cell/notebook-cell.scss +185 -0
- package/src/notebook-cell/notebook-cell.spec.ts +11 -0
- package/src/notebook-cell/notebook-cell.stories.js +87 -0
- package/src/notebook-cell/notebook-cell.ts +300 -0
- package/src/radio/radio.scss +3 -0
- package/src/radio/radio.spec.ts +11 -0
- package/src/radio/radio.stories.js +56 -0
- package/src/radio/radio.ts +18 -0
- package/src/select/select.scss +16 -0
- package/src/select/select.spec.ts +11 -0
- package/src/select/select.stories.js +57 -0
- package/src/select/select.ts +18 -0
- package/src/side-sheet/side-sheet.scss +49 -0
- package/src/side-sheet/side-sheet.spec.ts +11 -0
- package/src/side-sheet/side-sheet.stories.js +96 -0
- package/src/side-sheet/side-sheet.ts +37 -0
- package/src/skeleton/_skeleton.styles.scss +24 -0
- package/src/skeleton/skeleton.stories.js +77 -0
- package/src/slider/slider-range.ts +16 -0
- package/src/slider/slider.spec.ts +11 -0
- package/src/slider/slider.stories.js +54 -0
- package/src/slider/slider.ts +16 -0
- package/src/snackbar/snackbar.scss +8 -0
- package/src/snackbar/snackbar.spec.ts +11 -0
- package/src/snackbar/snackbar.stories.js +42 -0
- package/src/snackbar/snackbar.ts +18 -0
- package/src/status-dialog/status-dialog.scss +204 -0
- package/src/status-dialog/status-dialog.spec.ts +48 -0
- package/src/status-dialog/status-dialog.stories.js +136 -0
- package/src/status-dialog/status-dialog.ts +188 -0
- package/src/status-header/_status-header.theme.scss +79 -0
- package/src/status-header/status-header-base.ts +42 -0
- package/src/status-header/status-header-item.scss +17 -0
- package/src/status-header/status-header-item.spec.ts +11 -0
- package/src/status-header/status-header-item.ts +32 -0
- package/src/status-header/status-header.scss +57 -0
- package/src/status-header/status-header.spec.ts +11 -0
- package/src/status-header/status-header.stories.js +114 -0
- package/src/status-header/status-header.ts +26 -0
- package/src/switch/switch.scss +17 -0
- package/src/switch/switch.spec.ts +11 -0
- package/src/switch/switch.stories.js +41 -0
- package/src/switch/switch.ts +18 -0
- package/src/tab/Overview.mdx +38 -0
- package/src/tab/tab-bar.spec.ts +11 -0
- package/src/tab/tab-bar.ts +16 -0
- package/src/tab/tab.scss +10 -0
- package/src/tab/tab.spec.ts +11 -0
- package/src/tab/tab.stories.js +30 -0
- package/src/tab/tab.ts +18 -0
- package/src/text-lockup/text-lockup.scss +66 -0
- package/src/text-lockup/text-lockup.spec.ts +11 -0
- package/src/text-lockup/text-lockup.stories.js +67 -0
- package/src/text-lockup/text-lockup.ts +55 -0
- package/src/textarea/textarea.spec.ts +11 -0
- package/src/textarea/textarea.stories.js +39 -0
- package/src/textarea/textarea.ts +19 -0
- package/src/textfield/textfield.scss +34 -0
- package/src/textfield/textfield.spec.ts +11 -0
- package/src/textfield/textfield.stories.js +60 -0
- package/src/textfield/textfield.ts +25 -0
- package/src/theme/_index.scss +46 -0
- package/src/theme/prebuilt/dark-theme.scss +17 -0
- package/src/theme/prebuilt/light-theme.scss +17 -0
- package/src/toolbar/toolbar.scss +37 -0
- package/src/toolbar/toolbar.spec.ts +11 -0
- package/src/toolbar/toolbar.stories.js +66 -0
- package/src/toolbar/toolbar.ts +27 -0
- package/src/tooltip/tooltip.scss +16 -0
- package/src/tooltip/tooltip.spec.ts +11 -0
- package/src/tooltip/tooltip.stories.js +72 -0
- package/src/tooltip/tooltip.ts +185 -0
- package/src/top-app-bar/top-app-bar-fixed.ts +23 -0
- package/src/top-app-bar/top-app-bar.scss +14 -0
- package/src/top-app-bar/top-app-bar.spec.ts +11 -0
- package/src/top-app-bar/top-app-bar.stories.js +41 -0
- package/src/top-app-bar/top-app-bar.ts +23 -0
- package/src/tree-list/tree-list-item.scss +96 -0
- package/src/tree-list/tree-list-item.spec.ts +11 -0
- package/src/tree-list/tree-list-item.ts +87 -0
- package/src/tree-list/tree-list.scss +13 -0
- package/src/tree-list/tree-list.spec.ts +11 -0
- package/src/tree-list/tree-list.stories.js +151 -0
- package/src/tree-list/tree-list.ts +53 -0
- package/src/typography/typography.scss +45 -0
- package/src/typography/typography.spec.ts +11 -0
- package/src/typography/typography.stories.js +23 -0
- package/src/typography/typography.ts +27 -0
- package/stories/Introduction.mdx +47 -0
- package/stories/color-use.mdx +509 -0
- package/stories/demos/dialog.component.html +187 -0
- package/stories/demos/dialog.component.js +57 -0
- package/stories/demos/grid.content.html +99 -0
- package/stories/demos/lorem-ipsum.content.html +338 -0
- package/stories/demos/material-web.content.html +2125 -0
- package/stories/demos/table-column-sorting.content.html +92 -0
- package/stories/demos/table-pagination.content.html +139 -0
- package/stories/demos/table-progress-indicator.content.html +77 -0
- package/stories/demos/table-row-selection.content.html +219 -0
- package/stories/demos/table.content.html +64 -0
- package/stories/demos/top-app-bar.component.js +57 -0
- package/stories/guide-representing-state.mdx +282 -0
- package/stories/info-and-help.mdx +484 -0
- package/stories/item-detail-and-editing.mdx +529 -0
- package/stories/markdown-elements.mdx +194 -0
- package/stories/writing-and-naming.mdx +157 -0
- package/tsconfig.json +34 -0
- package/tsconfig.lib.json +17 -0
- package/tsconfig.spec.json +14 -0
- package/types.d.ts +15 -0
- package/vite.config.js +58 -0
@@ -0,0 +1,117 @@
|
|
1
|
+
import './empty-state';
|
2
|
+
import '../icon/icon';
|
3
|
+
import '../card/card';
|
4
|
+
import '../button/button';
|
5
|
+
|
6
|
+
export default {
|
7
|
+
title: 'Components/Empty state',
|
8
|
+
args: {
|
9
|
+
headline: "You don't have access to this area",
|
10
|
+
subtitle:
|
11
|
+
"You don't have permission to view this application.\nPlease contact your system administrator for further details.",
|
12
|
+
action: false,
|
13
|
+
twoActions: true,
|
14
|
+
icon: 'work',
|
15
|
+
},
|
16
|
+
};
|
17
|
+
|
18
|
+
// Page empty state
|
19
|
+
export const Page = ({ headline, subtitle, action, twoActions, icon }) => {
|
20
|
+
return `
|
21
|
+
<cv-empty-state
|
22
|
+
headline="${headline}"
|
23
|
+
subtitle="${subtitle}"
|
24
|
+
icon="${icon}"
|
25
|
+
>
|
26
|
+
${
|
27
|
+
action && !twoActions
|
28
|
+
? '<cv-button slot="buttons">Button text</cv-button>'
|
29
|
+
: ''
|
30
|
+
}
|
31
|
+
${
|
32
|
+
twoActions
|
33
|
+
? '<cv-button slot="buttons">Button text</cv-button>\n\
|
34
|
+
<cv-button slot="buttons">Button text</cv-button>'
|
35
|
+
: ''
|
36
|
+
}
|
37
|
+
</cv-empty-state>`;
|
38
|
+
};
|
39
|
+
|
40
|
+
export const PageTitleOnly = Page.bind({});
|
41
|
+
PageTitleOnly.args = {
|
42
|
+
subtitle: '',
|
43
|
+
action: false,
|
44
|
+
twoActions: false,
|
45
|
+
};
|
46
|
+
export const PageWithSubtitle = Page.bind({});
|
47
|
+
PageWithSubtitle.args = {
|
48
|
+
action: false,
|
49
|
+
twoActions: false,
|
50
|
+
};
|
51
|
+
export const PageOneAction = Page.bind({});
|
52
|
+
PageOneAction.args = {
|
53
|
+
subtitle: '',
|
54
|
+
action: true,
|
55
|
+
twoActions: false,
|
56
|
+
};
|
57
|
+
export const PageTwoActions = Page.bind({});
|
58
|
+
PageTwoActions.args = {
|
59
|
+
subtitle: '',
|
60
|
+
action: false,
|
61
|
+
twoActions: true,
|
62
|
+
};
|
63
|
+
|
64
|
+
// Card empty state
|
65
|
+
const Card = ({
|
66
|
+
cardOutlined,
|
67
|
+
cardTitle,
|
68
|
+
headline,
|
69
|
+
subtitle,
|
70
|
+
action,
|
71
|
+
twoActions,
|
72
|
+
}) => {
|
73
|
+
return `
|
74
|
+
<cv-card
|
75
|
+
cardTitle='${cardTitle}'
|
76
|
+
${cardOutlined ? 'outlined' : ''}
|
77
|
+
>
|
78
|
+
<cv-empty-state
|
79
|
+
headline="${headline}"
|
80
|
+
subtitle="${subtitle}"
|
81
|
+
card
|
82
|
+
>
|
83
|
+
${
|
84
|
+
action && !twoActions
|
85
|
+
? '<cv-button slot="buttons">Button text</cv-button>'
|
86
|
+
: ''
|
87
|
+
}
|
88
|
+
${
|
89
|
+
twoActions
|
90
|
+
? '<cv-button slot="buttons">Button text</cv-button>\n\
|
91
|
+
<cv-button slot="buttons">Button text</cv-button>'
|
92
|
+
: ''
|
93
|
+
}
|
94
|
+
</cv-empty-state>
|
95
|
+
</cv-card>
|
96
|
+
`;
|
97
|
+
};
|
98
|
+
|
99
|
+
export const CardNoAction = Card.bind({});
|
100
|
+
CardNoAction.args = {
|
101
|
+
cardOutlined: false,
|
102
|
+
action: false,
|
103
|
+
twoActions: false,
|
104
|
+
headline: '',
|
105
|
+
subtitle: "You don't have access to this area",
|
106
|
+
cardTitle: 'Card Title',
|
107
|
+
};
|
108
|
+
|
109
|
+
export const CardWithAction = Card.bind({});
|
110
|
+
CardWithAction.args = {
|
111
|
+
cardOutlined: false,
|
112
|
+
action: true,
|
113
|
+
twoActions: false,
|
114
|
+
headline: '',
|
115
|
+
subtitle: "You don't have access to this area",
|
116
|
+
cardTitle: 'Card Title',
|
117
|
+
};
|
@@ -0,0 +1,61 @@
|
|
1
|
+
import { css, unsafeCSS } from 'lit';
|
2
|
+
import { LitElement, html } from 'lit';
|
3
|
+
import { customElement, property } from 'lit/decorators.js';
|
4
|
+
import styles from './empty-state.scss?inline';
|
5
|
+
import '../icon/icon';
|
6
|
+
|
7
|
+
declare global {
|
8
|
+
interface HTMLElementTagNameMap {
|
9
|
+
'cv-empty-state': CovalentEmptyState;
|
10
|
+
}
|
11
|
+
}
|
12
|
+
|
13
|
+
@customElement('cv-empty-state')
|
14
|
+
export class CovalentEmptyState extends LitElement {
|
15
|
+
static override styles = [
|
16
|
+
css`
|
17
|
+
${unsafeCSS(styles)}
|
18
|
+
`,
|
19
|
+
];
|
20
|
+
|
21
|
+
@property({ type: String }) headline = '';
|
22
|
+
@property({ type: String }) subtitle = '';
|
23
|
+
@property({ type: String }) icon = '';
|
24
|
+
@property({ type: Boolean }) card = false;
|
25
|
+
override render() {
|
26
|
+
return html`
|
27
|
+
<div
|
28
|
+
class="content mdc-typography"
|
29
|
+
style=${this.card ? 'width: 632px; height: 300px;' : ''}
|
30
|
+
>
|
31
|
+
${this.icon
|
32
|
+
? html` <div class="icon-background">
|
33
|
+
<cv-icon class="covalent-icon">${this.icon}</cv-icon>
|
34
|
+
</div>`
|
35
|
+
: ''}
|
36
|
+
${this.headline
|
37
|
+
? html`<h6 class="mdc-typography--headline6">${this.headline}</h6>`
|
38
|
+
: ''}
|
39
|
+
${this.subtitle
|
40
|
+
? html` <p
|
41
|
+
key="{line}"
|
42
|
+
class="mdc-typography--body2"
|
43
|
+
style=${this.headline ? '' : 'margin-top:16px;'}
|
44
|
+
>
|
45
|
+
${this.subtitle.split(/\n/).map((line) => {
|
46
|
+
return html`${line}<br />`;
|
47
|
+
})}
|
48
|
+
</p>`
|
49
|
+
: ''}
|
50
|
+
<div
|
51
|
+
class="buttonContainer"
|
52
|
+
style=${this.subtitle ? '' : 'margin-top:0;'}
|
53
|
+
>
|
54
|
+
<slot name="buttons"></slot>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
`;
|
58
|
+
}
|
59
|
+
}
|
60
|
+
|
61
|
+
export default CovalentEmptyState;
|
@@ -0,0 +1,108 @@
|
|
1
|
+
import { Canvas, DocsContainer, Meta, Story } from '@storybook/blocks';
|
2
|
+
import './expansion-panel';
|
3
|
+
import './expansion-panel-item';
|
4
|
+
import '../button/button';
|
5
|
+
import incorrectExample from './expansion-panel-incorrect-example.png';
|
6
|
+
|
7
|
+
import * as ExpansionPanelStories from './expansion-panel.stories';
|
8
|
+
|
9
|
+
<Meta of={ExpansionPanelStories} />
|
10
|
+
|
11
|
+
<style>
|
12
|
+
{`
|
13
|
+
#story--example-button--outlined,
|
14
|
+
#story--example-button--text {
|
15
|
+
margin-right: 8px;
|
16
|
+
}
|
17
|
+
.buttonFooter{
|
18
|
+
display:flex;
|
19
|
+
align-items:center;
|
20
|
+
}
|
21
|
+
.buttonContainer {
|
22
|
+
margin-left:auto;
|
23
|
+
}
|
24
|
+
cv-button {
|
25
|
+
margin-left:5px;
|
26
|
+
}
|
27
|
+
img {
|
28
|
+
width:550px;
|
29
|
+
}
|
30
|
+
`}
|
31
|
+
</style>
|
32
|
+
|
33
|
+
# Expansion panel
|
34
|
+
|
35
|
+
## Anatomy
|
36
|
+
|
37
|
+
Set of expandable panels stacked up similar to data table.
|
38
|
+
|
39
|
+
#### Interactions and behavior
|
40
|
+
|
41
|
+
- Click on the expandable panel anywhere to get the extra information.
|
42
|
+
- Unexpanded items group into single cards, one before and one after the open panel.
|
43
|
+
- The expanded panel separates into its own card. Only one panel may be open at a time.
|
44
|
+
|
45
|
+
<Canvas>
|
46
|
+
<cv-expansion-panel titleWidth="16em">
|
47
|
+
<cv-expansion-panel-item title="Title" contentPreview="Content preview">
|
48
|
+
<div slot="content">Content</div>
|
49
|
+
</cv-expansion-panel-item>
|
50
|
+
|
51
|
+
<cv-expansion-panel-item title="Lorem ipsum dolor" contentPreview="Content preview">
|
52
|
+
<div slot="content">Content</div>
|
53
|
+
</cv-expansion-panel-item>
|
54
|
+
|
55
|
+
<cv-expansion-panel-item title="Lorem ipsum dolor" contentPreview="Content preview">
|
56
|
+
<div slot="content">Content</div>
|
57
|
+
</cv-expansion-panel-item>
|
58
|
+
|
59
|
+
<cv-expansion-panel-item title="Lorem ipsum dolor" contentPreview="Content preview">
|
60
|
+
<div slot="content">Content</div>
|
61
|
+
</cv-expansion-panel-item>
|
62
|
+
|
63
|
+
</cv-expansion-panel>
|
64
|
+
</Canvas>
|
65
|
+
|
66
|
+
---
|
67
|
+
|
68
|
+
## Common mistakes
|
69
|
+
|
70
|
+
#### Call to action placement on expanded panel
|
71
|
+
|
72
|
+
Do not add any call to action (button/link) on the expansion panel header because
|
73
|
+
the expansion panel header is clickable and when clicked on expanded state, it
|
74
|
+
collapses the panel. If absolutely needed, the call to actions can be added at
|
75
|
+
the bottom of expanded region.
|
76
|
+
|
77
|
+
##### Correct
|
78
|
+
|
79
|
+
Call to action is located in the footer.
|
80
|
+
|
81
|
+
<Canvas>
|
82
|
+
<form>
|
83
|
+
<cv-expansion-panel titleWidth="16em">
|
84
|
+
<cv-expansion-panel-item title="Title" contentPreview="Content preview" showFooter>
|
85
|
+
<div slot="content">
|
86
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
87
|
+
</div>
|
88
|
+
|
89
|
+
<div slot="footer" class="buttonFooter">
|
90
|
+
<div>You have unsaved changes</div>
|
91
|
+
|
92
|
+
<div class="buttonContainer">
|
93
|
+
<cv-button outlined label="Cancel" />
|
94
|
+
|
95
|
+
<cv-button raised label="Save" class="primary accent" />
|
96
|
+
</div>
|
97
|
+
</div>
|
98
|
+
</cv-expansion-panel-item>
|
99
|
+
</cv-expansion-panel>
|
100
|
+
|
101
|
+
</form>
|
102
|
+
</Canvas>
|
103
|
+
|
104
|
+
##### Incorrect
|
105
|
+
|
106
|
+
Call to action is located in the header.
|
107
|
+
|
108
|
+
<img src={incorrectExample} alt="Incorrect footer use" />
|
Binary file
|
@@ -0,0 +1,243 @@
|
|
1
|
+
:host([isTopPanel]) {
|
2
|
+
.panel {
|
3
|
+
border-radius: 8px 8px 0 0;
|
4
|
+
}
|
5
|
+
}
|
6
|
+
|
7
|
+
:host([isBottomPanel]) {
|
8
|
+
.panel {
|
9
|
+
border-radius: 0 0 8px 8px;
|
10
|
+
border: none;
|
11
|
+
}
|
12
|
+
}
|
13
|
+
|
14
|
+
:host([isSinglePanel]) {
|
15
|
+
.panel {
|
16
|
+
border-radius: 8px;
|
17
|
+
border: none;
|
18
|
+
}
|
19
|
+
}
|
20
|
+
|
21
|
+
:host([isInnerPanel]) {
|
22
|
+
.panel {
|
23
|
+
border-radius: 0;
|
24
|
+
}
|
25
|
+
}
|
26
|
+
|
27
|
+
:host([open][isInnerPanel]) {
|
28
|
+
.panel {
|
29
|
+
border-radius: 8px;
|
30
|
+
margin-top: 16px;
|
31
|
+
margin-bottom: 16px;
|
32
|
+
border-bottom: 0;
|
33
|
+
}
|
34
|
+
|
35
|
+
.header {
|
36
|
+
min-height: 64px;
|
37
|
+
max-height: 64px;
|
38
|
+
}
|
39
|
+
|
40
|
+
.dropdown {
|
41
|
+
grid-template-rows: 1fr;
|
42
|
+
}
|
43
|
+
|
44
|
+
.closedIcon {
|
45
|
+
display: none;
|
46
|
+
}
|
47
|
+
|
48
|
+
.openedIcon {
|
49
|
+
display: inline-block;
|
50
|
+
}
|
51
|
+
|
52
|
+
::slotted([slot='content']) {
|
53
|
+
padding-bottom: 16px;
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
:host([open][isTopPanel]) {
|
58
|
+
.panel {
|
59
|
+
border-radius: 8px;
|
60
|
+
margin-bottom: 16px;
|
61
|
+
border-bottom: 0;
|
62
|
+
}
|
63
|
+
|
64
|
+
.header {
|
65
|
+
min-height: 64px;
|
66
|
+
max-height: 64px;
|
67
|
+
}
|
68
|
+
|
69
|
+
.dropdown {
|
70
|
+
grid-template-rows: 1fr;
|
71
|
+
}
|
72
|
+
|
73
|
+
.closedIcon {
|
74
|
+
display: none;
|
75
|
+
}
|
76
|
+
|
77
|
+
.openedIcon {
|
78
|
+
display: inline-block;
|
79
|
+
}
|
80
|
+
|
81
|
+
::slotted([slot='content']) {
|
82
|
+
padding-bottom: 16px;
|
83
|
+
}
|
84
|
+
}
|
85
|
+
|
86
|
+
:host([open][isBottomPanel]) {
|
87
|
+
.panel {
|
88
|
+
border-radius: 8px;
|
89
|
+
margin-top: 16px;
|
90
|
+
border-bottom: 0;
|
91
|
+
}
|
92
|
+
|
93
|
+
.header {
|
94
|
+
min-height: 64px;
|
95
|
+
max-height: 64px;
|
96
|
+
}
|
97
|
+
|
98
|
+
.dropdown {
|
99
|
+
grid-template-rows: 1fr;
|
100
|
+
}
|
101
|
+
|
102
|
+
.closedIcon {
|
103
|
+
display: none;
|
104
|
+
}
|
105
|
+
|
106
|
+
.openedIcon {
|
107
|
+
display: inline-block;
|
108
|
+
}
|
109
|
+
|
110
|
+
::slotted([slot='content']) {
|
111
|
+
padding-bottom: 16px;
|
112
|
+
}
|
113
|
+
}
|
114
|
+
|
115
|
+
:host([open][isSinglePanel]) {
|
116
|
+
.header {
|
117
|
+
min-height: 64px;
|
118
|
+
max-height: 64px;
|
119
|
+
}
|
120
|
+
|
121
|
+
.dropdown {
|
122
|
+
grid-template-rows: 1fr;
|
123
|
+
}
|
124
|
+
|
125
|
+
.closedIcon {
|
126
|
+
display: none;
|
127
|
+
}
|
128
|
+
|
129
|
+
.openedIcon {
|
130
|
+
display: inline-block;
|
131
|
+
}
|
132
|
+
|
133
|
+
::slotted([slot='content']) {
|
134
|
+
padding-bottom: 16px;
|
135
|
+
}
|
136
|
+
}
|
137
|
+
|
138
|
+
:host([belowOpenInnerPanel]) {
|
139
|
+
.panel {
|
140
|
+
border-radius: 8px 8px 0 0;
|
141
|
+
}
|
142
|
+
}
|
143
|
+
|
144
|
+
:host([aboveOpenInnerPanel]) {
|
145
|
+
.panel {
|
146
|
+
border-radius: 0 0 8px 8px;
|
147
|
+
border-bottom: none;
|
148
|
+
}
|
149
|
+
}
|
150
|
+
|
151
|
+
:host([separateSinglePanel]) {
|
152
|
+
.panel {
|
153
|
+
border-radius: 8px;
|
154
|
+
border-bottom: none;
|
155
|
+
}
|
156
|
+
}
|
157
|
+
|
158
|
+
:host {
|
159
|
+
.panel {
|
160
|
+
border-bottom: 1px solid var(--mdc-theme-border, rgba(0, 0, 0, 12%));
|
161
|
+
background-color: var(--cv-theme-surface-container, #ffffff);
|
162
|
+
transition:
|
163
|
+
margin-bottom 0.5s,
|
164
|
+
margin-top 0.5s;
|
165
|
+
}
|
166
|
+
|
167
|
+
.header {
|
168
|
+
min-height: 48px;
|
169
|
+
max-height: 48px;
|
170
|
+
padding: 0 24px;
|
171
|
+
display: flex;
|
172
|
+
align-items: center;
|
173
|
+
transition:
|
174
|
+
min-height 0.5s,
|
175
|
+
max-height 0.5s;
|
176
|
+
cursor: pointer;
|
177
|
+
}
|
178
|
+
|
179
|
+
.title {
|
180
|
+
width: var(--cv-expansion-panel-item-title-width, 200px);
|
181
|
+
overflow: hidden;
|
182
|
+
text-overflow: ellipsis;
|
183
|
+
white-space: nowrap;
|
184
|
+
color: var(--mdc-theme-text-primary-on-background, rgba(0, 0, 0, 87%));
|
185
|
+
font-family: var(--mdc-typography-body1-font-family, Arial);
|
186
|
+
font-size: var(--mdc-typography-body1-font-size, 14px);
|
187
|
+
font-style: normal;
|
188
|
+
font-weight: var(--mdc-typography-body1-font-weight, 400);
|
189
|
+
line-height: var(--mdc-typography-body1-line-height, 20px);
|
190
|
+
letter-spacing: 0.25px;
|
191
|
+
}
|
192
|
+
|
193
|
+
.contentPreview {
|
194
|
+
overflow: hidden;
|
195
|
+
text-overflow: ellipsis;
|
196
|
+
white-space: nowrap;
|
197
|
+
padding-left: 16px;
|
198
|
+
color: var(--mdc-theme-text-secondary-on-background, rgba(0, 0, 0, 54%));
|
199
|
+
font-family: var(--mdc-typography-body1-font-family, Arial);
|
200
|
+
font-size: var(--mdc-typography-body1-font-size, 14px);
|
201
|
+
font-style: normal;
|
202
|
+
font-weight: var(--mdc-typography-body1-font-weight, 400);
|
203
|
+
line-height: var(--mdc-typography-body1-line-height, 20px);
|
204
|
+
letter-spacing: 0.25px;
|
205
|
+
}
|
206
|
+
|
207
|
+
cv-icon {
|
208
|
+
padding-left: 16px;
|
209
|
+
margin-left: auto;
|
210
|
+
}
|
211
|
+
|
212
|
+
.dropdown {
|
213
|
+
display: grid;
|
214
|
+
grid-template-rows: 0fr;
|
215
|
+
transition: grid-template-rows 0.5s;
|
216
|
+
color: var(--mdc-theme-text-primary-on-background, rgba(0, 0, 0, 87%));
|
217
|
+
font-family: var(--mdc-typography-body1-font-family, Arial);
|
218
|
+
font-size: var(--mdc-typography-body1-font-size, 14px);
|
219
|
+
font-style: normal;
|
220
|
+
font-weight: var(--mdc-typography-body1-font-weight, 400);
|
221
|
+
line-height: var(--mdc-typography-body1-line-height, 20px);
|
222
|
+
letter-spacing: 0.25px;
|
223
|
+
}
|
224
|
+
|
225
|
+
.content {
|
226
|
+
overflow-y: hidden;
|
227
|
+
}
|
228
|
+
|
229
|
+
.content slot {
|
230
|
+
display: block;
|
231
|
+
padding: 0 24px;
|
232
|
+
}
|
233
|
+
|
234
|
+
.footer {
|
235
|
+
overflow-y: hidden;
|
236
|
+
padding: 16px 24px;
|
237
|
+
border-top: 1px solid var(--mdc-theme-border, rgba(0, 0, 0, 12%));
|
238
|
+
}
|
239
|
+
|
240
|
+
.openedIcon {
|
241
|
+
display: none;
|
242
|
+
}
|
243
|
+
}
|
@@ -0,0 +1,95 @@
|
|
1
|
+
import { LitElement, css, html, unsafeCSS } from 'lit';
|
2
|
+
import { customElement, property } from 'lit/decorators.js';
|
3
|
+
import styles from './expansion-panel-item.scss?inline';
|
4
|
+
import '../icon/icon';
|
5
|
+
|
6
|
+
@customElement('cv-expansion-panel-item')
|
7
|
+
export class CovalentExpansionPanelItem extends LitElement {
|
8
|
+
static override styles = [
|
9
|
+
css`
|
10
|
+
${unsafeCSS(styles)}
|
11
|
+
`,
|
12
|
+
];
|
13
|
+
|
14
|
+
@property({ type: Number }) index = 0;
|
15
|
+
|
16
|
+
@property({ type: Boolean, reflect: true, attribute: 'open' }) open = false;
|
17
|
+
@property({ type: Boolean, reflect: true, attribute: 'isTopPanel' })
|
18
|
+
isTopPanel = false;
|
19
|
+
@property({ type: Boolean, reflect: true, attribute: 'isInnerPanel' })
|
20
|
+
isInnerPanel = false;
|
21
|
+
@property({ type: Boolean, reflect: true, attribute: 'isBottomPanel' })
|
22
|
+
isBottomPanel = false;
|
23
|
+
@property({ type: Boolean, reflect: true, attribute: 'isSinglePanel' })
|
24
|
+
isSinglePanel = false;
|
25
|
+
|
26
|
+
@property({ type: Boolean, reflect: true, attribute: 'belowOpenInnerPanel' })
|
27
|
+
belowOpenInnerPanel = false;
|
28
|
+
@property({ type: Boolean, reflect: true, attribute: 'aboveOpenInnerPanel' })
|
29
|
+
aboveOpenInnerPanel = false;
|
30
|
+
// if the panel right below the top panel or right above the bottom panel is opened,
|
31
|
+
// the very top or bottom panel becomes a single panel
|
32
|
+
@property({ type: Boolean, reflect: true, attribute: 'separateSinglePanel' })
|
33
|
+
separateSinglePanel = false;
|
34
|
+
|
35
|
+
@property({ type: String }) title = 'Title';
|
36
|
+
@property({ type: String }) contentPreview = '';
|
37
|
+
@property({ type: Boolean, reflect: true }) showFooter = false;
|
38
|
+
@property({ type: Boolean, reflect: true }) noSurface = false;
|
39
|
+
|
40
|
+
render() {
|
41
|
+
return html`
|
42
|
+
<div class="panel">
|
43
|
+
<div class="header" @click=${this._toggleContent}>
|
44
|
+
<span class="title">${this.title}<slot name="title"></slot></span>
|
45
|
+
<span class="contentPreview"
|
46
|
+
>${this.contentPreview}<slot name="preview"></slot
|
47
|
+
></span>
|
48
|
+
<cv-icon class="closedIcon">expand_more</cv-icon>
|
49
|
+
<cv-icon class="openedIcon">expand_less</cv-icon>
|
50
|
+
</div>
|
51
|
+
|
52
|
+
<div class="dropdown">
|
53
|
+
<div class="content">
|
54
|
+
<slot name="content"></slot>
|
55
|
+
${this.showFooter
|
56
|
+
? html`
|
57
|
+
<div class="footer">
|
58
|
+
<slot name="footer"></slot>
|
59
|
+
</div>
|
60
|
+
`
|
61
|
+
: ''}
|
62
|
+
</div>
|
63
|
+
</div>
|
64
|
+
</div>
|
65
|
+
`;
|
66
|
+
}
|
67
|
+
|
68
|
+
resetPanel() {
|
69
|
+
this.belowOpenInnerPanel = false;
|
70
|
+
this.aboveOpenInnerPanel = false;
|
71
|
+
this.separateSinglePanel = false;
|
72
|
+
this.open = false;
|
73
|
+
}
|
74
|
+
|
75
|
+
private _toggleContent() {
|
76
|
+
this.open = !this.open;
|
77
|
+
|
78
|
+
const event = new CustomEvent('cv-expansionPanel-togglePanel', {
|
79
|
+
detail: {
|
80
|
+
message: `Panel opened: ${this}`,
|
81
|
+
bubbles: true,
|
82
|
+
composed: true,
|
83
|
+
open: this.open,
|
84
|
+
index: this.index,
|
85
|
+
},
|
86
|
+
});
|
87
|
+
window.dispatchEvent(event);
|
88
|
+
}
|
89
|
+
}
|
90
|
+
|
91
|
+
declare global {
|
92
|
+
interface HTMLElementTagNameMap {
|
93
|
+
'cv-expansion-panel-item': CovalentExpansionPanelItem;
|
94
|
+
}
|
95
|
+
}
|
@@ -0,0 +1,11 @@
|
|
1
|
+
/**
|
2
|
+
* @vitest-environment jsdom
|
3
|
+
*/
|
4
|
+
import { it, describe, expect } from 'vitest';
|
5
|
+
import { CovalentExpansionPanel } from './expansion-panel';
|
6
|
+
|
7
|
+
describe('Expansion panel', () => {
|
8
|
+
it('should work', () => {
|
9
|
+
expect(new CovalentExpansionPanel()).toBeDefined();
|
10
|
+
});
|
11
|
+
});
|
@@ -0,0 +1,76 @@
|
|
1
|
+
import './expansion-panel';
|
2
|
+
import './expansion-panel-item';
|
3
|
+
import '../icon/icon';
|
4
|
+
import '../action-ribbon/action-ribbon';
|
5
|
+
import '../button/button';
|
6
|
+
import '../icon/icon';
|
7
|
+
|
8
|
+
export default {
|
9
|
+
title: 'Components/Expansion panel',
|
10
|
+
args: {
|
11
|
+
icon: 'description',
|
12
|
+
noSurface: false,
|
13
|
+
},
|
14
|
+
parameters: {
|
15
|
+
layout: 'centered',
|
16
|
+
},
|
17
|
+
};
|
18
|
+
|
19
|
+
export const Basic = ({ icon, noSurface }) => {
|
20
|
+
return `
|
21
|
+
<cv-expansion-panel ${noSurface ? 'noSurface' : ''} titleWidth='16em'>
|
22
|
+
|
23
|
+
<cv-expansion-panel-item
|
24
|
+
title="Title"
|
25
|
+
contentPreview="Content preview"
|
26
|
+
showFooter
|
27
|
+
>
|
28
|
+
<div slot="content">
|
29
|
+
Culpa qui officia deserunt mollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
30
|
+
</div>
|
31
|
+
<div slot="footer">
|
32
|
+
Basic footer
|
33
|
+
</div>
|
34
|
+
</cv-expansion-panel-item>
|
35
|
+
|
36
|
+
<cv-expansion-panel-item
|
37
|
+
title="Lorem ipsum dolor sit amet"
|
38
|
+
contentPreview="Content preview"
|
39
|
+
showFooter
|
40
|
+
>
|
41
|
+
<div slot="content">Mxollit anim id est laborum.Lorem ipsum dolor sit amet, consectetur adipiscing elit.</div>
|
42
|
+
<div slot="footer" style="display:flex; align-items:center">
|
43
|
+
<div style="color:rgba(255, 255, 255, 0.54)">You have unsaved changes</div>
|
44
|
+
<div style="margin-left:auto">
|
45
|
+
<cv-button outlined label="Cancel"></cv-button>
|
46
|
+
<cv-button raised label="Save" class="primary accent"></cv-button>
|
47
|
+
</div>
|
48
|
+
</div>
|
49
|
+
</cv-expansion-panel-item>
|
50
|
+
|
51
|
+
<cv-expansion-panel-item
|
52
|
+
title="Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do"
|
53
|
+
contentPreview="Content preview"
|
54
|
+
>
|
55
|
+
<div slot="content">
|
56
|
+
Content
|
57
|
+
</div>
|
58
|
+
</cv-expansion-panel-item>
|
59
|
+
|
60
|
+
<cv-expansion-panel-item
|
61
|
+
title="Lorem ipsum dolor"
|
62
|
+
>
|
63
|
+
<div slot="content">
|
64
|
+
Content
|
65
|
+
</div>
|
66
|
+
</cv-expansion-panel-item>
|
67
|
+
|
68
|
+
</cv-expansion-panel>
|
69
|
+
`;
|
70
|
+
};
|
71
|
+
|
72
|
+
export const NoSurface = Basic.bind({});
|
73
|
+
|
74
|
+
NoSurface.args = {
|
75
|
+
noSurface: true,
|
76
|
+
};
|