Skip to content

Commit d18e72b

Browse files
majidsajadizeinab-nsrzeynab.nasiri
authored
Add bottom sheet (#177)
* Add bottom sheet (#170) * feat: add TapTooltip component boilerplates * feat: add icon to button component * fix: fix custom element name * feat: add tooltip story * feat: add shape prop to tap button * feat: add shape prop to tap button * feat: add button and dynamic label to tooltip * fix: fix UI issues * fix: pass icon prop to button in TemplateResult type * feat: add simple story decorator to tooltip's story * feat: add tooltip pointer styles * feat: handle tooltip props * feat: add simple story decorator to tooltip's story * feat: add floating-ui/dom * feat: add story decorator and improve stories * fix: UI issue * chore: rename component * fix: remove referenceId prop * chore: remove unused codes * fix: dismissible prop style * fix: fix dismiss icon issue * fix: triggering on click * fix: import icon button * chore: minor improvement * chore: add argTypes * chore: minor improvements on styles * chore: minor improvements on styles * chore: remove font from story decorator * chore: improve descriptions * fix: change attribute name * fix: use query decorator instead of querySelector * chore: add label size variable * fix: remove decorator * fix: provide target element as slot * fix: fix UI issue * feat: add documentation * fix: revert documentations * chore: add documentation * fix: linter issues * feat: add bottom sheet boilerplates * feat: add bottomsheet header and body * chore: remove unused imports * feat: add grabber and dismissible prop + close animation * feat: add close and open animations * chore: remove unused import * feat: pass body content as slot * fix: passing boolean attr * chore: rename open prop to isOpen * feat: add storybook's argTypes * fix: animations and container style * feat: add touch handlers * chore: minor improvemetns on naming and modularization * chore: rewrite functions in arrow syntax * chore: minor improvemetns on naming and modularization * fix: update disapper prop on close state * fix: dismiss on dimmer click * chore: add attr name for isExpanded * chore: minor improvement * feat: update JSDOC for bottom sheet * fix: style issue * chore: minor improvement * chore: improvement on private property * fix: prevent triggering touch events when grabber is disable * fix: align bottom sheet in center of screen + animation improvements * fix: add max visible height for not expanded bottom sheet content * feat: implement slot header, render default if not provided * chore: minor improvement * fix: bottom sheet loading transition changed to from bottom * chore: minor improvement on DOC, styles and story * chore: remove unused comment * chore: renam header slot * chore: add dimmer csspart * chore: rename open and expanded props * chore: rename open and expanded props * chore: rename dismissible prop * chore: minor improvements on naming and docs * feat: add bottom sheet to element config * chore: update imports --------- Co-authored-by: zeynab.nasiri <zeynab.nasiri@tapsi.cab> * Fix bottom-sheet size change --------- Co-authored-by: Zeinab Nasiri <zeinab.nasiri1996@gmail.com> Co-authored-by: zeynab.nasiri <zeynab.nasiri@tapsi.cab>
1 parent 3cd4b97 commit d18e72b

File tree

6 files changed

+473
-0
lines changed

6 files changed

+473
-0
lines changed

docs/components/[component].md

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import '../../src/bottom-navigation-item';
1515
import '../../src/base-button';
1616
import '../../src/button';
1717
import '../../src/base-button';
18+
import '../../src/bottom-sheet'
1819
import '../../src/checkbox';
1920
import '../../src/divider';
2021
import '../../src/icon-button';

docs/components/elements-config.json

+11
Original file line numberDiff line numberDiff line change
@@ -252,5 +252,16 @@
252252
"simple": "<tap-chip size=\"md\" selected>مسافر</tap-chip>\n <tap-chip>راننده</tap-chip>"
253253
}
254254
}
255+
},
256+
"tap-bottom-sheet": {
257+
"propertyDefaultValues": {
258+
"title": "عنوان"
259+
},
260+
"slotKnobs": {
261+
"bottom-sheet-body": {
262+
"security": "<div slot=\"bottom-sheet-body\" style=\"width: 100%\">\n <div>\n <tap-row navigable>\n <tap-icon-button slot=\"leading\" variant=\"ghost\">\n <tap-icon-pin-wave-fill></tap-icon-pin-wave-fill>\n </tap-icon-button>\n <div slot=\"content\">\n <h3 style=\"margin: 0;\">سفرتان را به اشتراک بگذارید</h3>\n <p style=\"margin: 0;\">اشتراک سفر با دوستان و آشنایان</p>\n </div>\n </tap-row>\n </div>\n <tap-divider></tap-divider>\n <div slot=\"bottom-sheet-body\" style=\"width: 100%\">\n <tap-row navigable>\n <tap-icon-button slot=\"leading\" variant=\"destructive\">\n <tap-icon-siren-fill></tap-icon-siren-fill>\n </tap-icon-button>\n <div slot=\"content\">\n <h3 style=\"margin: 0; color: var(--tap-sys-color-surface-negative)\">در شرایط خطرناکی هستید؟</h3>\n <p style=\"margin: 0;\">برقراری تماس با تیم امنیت تپسی</p>\n </div>\n </tap-row>\n </div>\n </div>",
263+
"tip": "<div slot=\"bottom-sheet-body\" style=\"width: 100%\">\n <div>\n <p style=\"padding: 0 1rem\">مبلغی که شما جهت قدردانی به سفیر می پردازید، بدون کسر کارمزد برای سفیر واریز می شود.</p>\n <p style=\"padding: 0 1rem;\" slot=\"content\">۱۲,۰۰۰ تومان</p>\n <tap-divider></tap-divider>\n <p style=\"padding: 0 1rem;\" slot=\"content\">۱۸,۰۰۰ تومان</p>\n <tap-divider></tap-divider>\n <p style=\"padding: 0 1rem;\" slot=\"content\">۲۵,۰۰۰ تومان</p>\n <tap-divider></tap-divider>\n <p style=\"padding: 0 1rem;\" slot=\"content\">مبلغ دلخواه</p>\n </div>\n </div>"
264+
}
265+
}
255266
}
256267
}
+92
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import { html, TemplateResult } from 'lit';
2+
import { Meta } from '@storybook/web-components';
3+
import './index.js';
4+
import '../tooltip';
5+
6+
export default {
7+
title: 'Components/Bottom Sheet',
8+
component: 'tap-bottom-sheet',
9+
parameters: {
10+
layout: 'fullscreen',
11+
},
12+
argTypes: {
13+
open: {
14+
control: 'boolean',
15+
description:
16+
'Controls the visibility of the bottom sheet. If true, the bottom sheet is visible.',
17+
},
18+
dismissible: {
19+
control: 'boolean',
20+
description:
21+
'Determines whether the bottom sheet can be dismissed by the user. If true, a close button is displayed, allowing the bottom sheet to be closed.',
22+
},
23+
hasDimmer: {
24+
control: 'boolean',
25+
description: 'Controls the presence of a dimmer overlay.',
26+
},
27+
title: {
28+
control: 'text',
29+
description:
30+
'Specifies the title displayed in the header of the bottom sheet.',
31+
},
32+
expanded: {
33+
control: 'boolean',
34+
description:
35+
'If true, the bottom sheet expands to 90% of the viewport height (90vh).',
36+
},
37+
showGrabber: {
38+
control: 'boolean',
39+
description: 'Controls the visibility of the grabber element.',
40+
},
41+
},
42+
decorators: [
43+
(Story: () => TemplateResult) => {
44+
return html`
45+
<style>
46+
body {
47+
overflow: hidden;
48+
}
49+
</style>
50+
${Story()}
51+
`;
52+
},
53+
],
54+
} as Meta;
55+
56+
interface Story<T> {
57+
(args: T): TemplateResult;
58+
args?: Partial<T>;
59+
argTypes?: Record<string, unknown>;
60+
}
61+
62+
interface ArgTypes {
63+
open?: boolean;
64+
disappear?: boolean;
65+
dismissible?: boolean;
66+
hasDimmer?: boolean;
67+
title?: string;
68+
expanded?: boolean;
69+
showGrabber?: boolean;
70+
}
71+
72+
const Template: Story<ArgTypes> = ({ title, open, hasDimmer }) => {
73+
return html` <tap-bottom-sheet
74+
title=${title}
75+
?open=${open}
76+
?has-dimmer=${hasDimmer}
77+
>
78+
<div
79+
slot="bottom-sheet-body"
80+
style="padding: 2rem; height: 100vh; overflow-x: auto; width: 100%; direction: ltr;"
81+
>
82+
<div>This is body.</div>
83+
</div>
84+
</tap-bottom-sheet>`;
85+
};
86+
87+
export const Simple = Template.bind({});
88+
Simple.args = {
89+
title: 'عنوان',
90+
open: true,
91+
hasDimmer: true,
92+
};
+121
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
import { css } from 'lit';
2+
3+
export default css`
4+
:host {
5+
display: flex;
6+
justify-content: center;
7+
}
8+
9+
.bottom-sheet {
10+
position: absolute;
11+
bottom: var(--tap-bottom-sheet-bottom, -100dvh);
12+
height: 90dvh;
13+
max-height: 90dvh;
14+
display: flex;
15+
flex-direction: column;
16+
transition: 0.3s;
17+
direction: rtl;
18+
max-width: 440px;
19+
width: 100%;
20+
background-color: var(
21+
--tap-bottom-sheet-background,
22+
var(--tap-sys-color-surface-primary)
23+
);
24+
box-sizing: border-box;
25+
font-family: var(--tap-font-family, var(--tap-sys-font-family));
26+
border-radius: 20px 20px 0 0;
27+
border: 1px solid var(--tap-palette-gray-200);
28+
border-bottom: 0;
29+
}
30+
31+
.bottom-sheet-dimmer {
32+
position: fixed;
33+
width: 100dvw;
34+
height: 100dvh;
35+
bottom: 0;
36+
background-color: #33323b4b;
37+
animation: fade-in 0.3s ease-in-out;
38+
}
39+
40+
.bottom-sheet-body {
41+
display: flex;
42+
width: 100%;
43+
background-color: inherit;
44+
flex-grow: 1;
45+
overflow-x: auto;
46+
overflow-y: var(--tap-bottom-sheet-content-overflow-y, scroll);
47+
}
48+
49+
.bottom-sheet-header {
50+
display: flex;
51+
align-items: center;
52+
padding-top: var(--tap-bottom-sheet-header-padding, 0);
53+
border-bottom: 1px solid var(--tap-palette-gray-200);
54+
}
55+
56+
.title {
57+
height: 52px;
58+
text-align: center;
59+
display: flex;
60+
justify-content: center;
61+
flex-grow: 1;
62+
align-items: center;
63+
}
64+
65+
.close-button {
66+
background-color: var(--tap-palette-gray-100);
67+
width: 32px;
68+
heigh: 32px;
69+
border-radius: 50%;
70+
position: absolute;
71+
left: 16px;
72+
display: flex;
73+
-webkit-tap-highlight-color: transparent;
74+
}
75+
76+
.grabber {
77+
width: 44px;
78+
height: 4px;
79+
border-radius: 2px;
80+
position: absolute;
81+
top: 8px;
82+
background-color: rgba(0, 0, 0, 0.12);
83+
right: 50%;
84+
transform: translateX(50%);
85+
}
86+
87+
.close {
88+
animation: slide-down 0.3s ease-in forwards;
89+
}
90+
91+
.open {
92+
animation: slide-up 0.3s ease-in forwards;
93+
}
94+
95+
@keyframes slide-down {
96+
from {
97+
transform: translateY(0);
98+
}
99+
to {
100+
transform: translateY(100%);
101+
}
102+
}
103+
104+
@keyframes slide-up {
105+
from {
106+
transform: translateY(100%);
107+
}
108+
to {
109+
transform: translateY(0);
110+
}
111+
}
112+
113+
@keyframes fade-in {
114+
from {
115+
opacity: 0;
116+
}
117+
to {
118+
opacity: 1;
119+
}
120+
}
121+
`;

0 commit comments

Comments
 (0)