Skip to content

Commit f4675c6

Browse files
authored
feat: add Button component and styles (#2914)
1 parent 4bc9ac4 commit f4675c6

File tree

17 files changed

+270
-92
lines changed

17 files changed

+270
-92
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@
234234
"prettier": "prettier '**/*.{js,mjs,ts,mts,jsx,tsx,md,json,yml}'",
235235
"prettier-fix": "yarn prettier --write",
236236
"fix-staged": "lint-staged --config .lintstagedrc.fix.json --concurrent 1",
237-
"start": "tsc --watch --sourceMap --declarationMap",
237+
"start": "tsc --watch --sourceMap",
238238
"start:css": "sass --watch src/styling/index.scss dist/css/index.css",
239239
"prepare": "husky install",
240240
"preversion": "yarn install",

src/components/Button/Button.tsx

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import type { ComponentProps } from 'react';
2+
import clsx from 'clsx';
3+
4+
export const Button = ({ className, ...props }: ComponentProps<'button'>) => (
5+
<button type='button' {...props} className={clsx('str-chat__button', className)} />
6+
);

src/components/Button/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export * from './Button';
Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
@use '../../../styling/utils';
2+
3+
.str-chat {
4+
.str-chat__button {
5+
@include utils.button-reset;
6+
position: relative; /* creates positioning context for pseudo ::after overlay */
7+
overflow: hidden;
8+
9+
cursor: pointer;
10+
11+
display: flex;
12+
align-items: center;
13+
justify-content: center;
14+
gap: var(--spacing-xs);
15+
//padding-inline: var(--spacing-md);
16+
//padding-block: var(--spacing-sm);
17+
/*
18+
min-width / min-height on buttons:
19+
- enforce a minimum tappable area
20+
- follow accessibility & platform guidelines
21+
- don’t affect layout unless the button would be too small
22+
- are about usability, not design polish
23+
*/
24+
min-height: var(--button-visual-height-lg);
25+
max-height: var(--button-visual-height-lg);
26+
27+
line-height: var(--typography-line-height-normal);
28+
border-radius: var(--button-radius-lg);
29+
30+
font-weight: var(--font-weight-w600);
31+
32+
&.str-chat__button--solid {
33+
&.str-chat__button--primary {
34+
background-color: var(--button-type-primary-bg);
35+
color: var(--button-type-primary-text);
36+
border-color: var(--button-type-primary-border);
37+
}
38+
39+
&.str-chat__button--secondary {
40+
background-color: var(--button-type-secondary-bg);
41+
color: var(--button-type-secondary-text);
42+
border-color: var(--button-type-secondary-border);
43+
}
44+
45+
&.str-chat__button--destructive {
46+
background-color: var(--button-type-destructive-bg);
47+
color: var(--button-type-destructive-text);
48+
border-color: var(--button-type-destructive-border);
49+
}
50+
51+
&:disabled {
52+
background-color: var(--state-bg-disabled);
53+
}
54+
}
55+
56+
&.str-chat__button--ghost {
57+
border-color: var(--button-style-ghost-border);
58+
background-color: var(--button-style-ghost-bg);
59+
60+
&.str-chat__button--primary {
61+
color: var(--button-style-ghost-text-primary);
62+
}
63+
64+
&.str-chat__button--secondary {
65+
color: var(--button-style-ghost-text-secondary);
66+
}
67+
68+
&.str-chat__button--destructive {
69+
color: var(--button-type-destructive-text-inverse);
70+
}
71+
}
72+
73+
&.str-chat__button--outline {
74+
// todo: designs not available
75+
//&.str-chat__button--primary {
76+
// background-color: var(--button-type-primary-bg);
77+
// color: var(--button-type-primary-text);
78+
// border-color: var(--button-type-primary-border);
79+
//}
80+
81+
&.str-chat__button--secondary {
82+
background-color: var(--button-style-outline-bg);
83+
color: var(--button-style-outline-text);
84+
border-color: var(--button-style-outline-border);
85+
}
86+
87+
// todo: designs not available
88+
&.str-chat__button--destructive {
89+
//background-color: var(--button-type-destructive-bg);
90+
color: var(--button-type-destructive-text-inverse);
91+
//border-color: var(--button-type-destructive-border);
92+
}
93+
}
94+
95+
&.str-chat__button--solid,
96+
&.str-chat__button--ghost {
97+
&:disabled {
98+
border: none;
99+
}
100+
}
101+
102+
&.str-chat__button--solid,
103+
&.str-chat__button--outline,
104+
&.str-chat__button--ghost {
105+
border-width: 1px;
106+
border-style: solid;
107+
108+
109+
&:not(:disabled):hover {
110+
@include utils.overlay-after(0.05);
111+
}
112+
113+
&:not(:disabled):active { // pressed
114+
@include utils.overlay-after(0.10);
115+
}
116+
117+
&:not(:disabled):focus-visible { // focused
118+
outline: 2px solid var(--border-utility-focus);
119+
}
120+
121+
&:disabled {
122+
color: var(--state-text-disabled);
123+
cursor: default;
124+
}
125+
}
126+
127+
&.str-chat__button--floating {
128+
box-shadow: var(--light-elevation-3);
129+
}
130+
}
131+
}
132+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { ComponentProps } from 'react';
2+
import clsx from 'clsx';
3+
4+
export const IconMicrophone = ({ className, ...props }: ComponentProps<'svg'>) => (
5+
<svg
6+
stroke='currentColor'
7+
viewBox='0 0 20 20'
8+
{...props}
9+
className={clsx('str-chat__icon--microphone', className)}
10+
xmlns='http://www.w3.org/2000/svg'
11+
>
12+
<path
13+
d='M10.0007 15.8332C12.5637 15.8332 14.7662 14.2906 15.7307 12.0832M10.0007 15.8332C7.43788 15.8332 5.23527 14.2906 4.27083 12.0832M10.0007 15.8332V17.7082M10.0007 13.1248C8.04476 13.1248 6.4591 11.5392 6.4591 9.58317V5.83317C6.4591 3.87716 8.04476 2.2915 10.0007 2.2915C11.9567 2.2915 13.5424 3.87716 13.5424 5.83317V9.58317C13.5424 11.5392 11.9567 13.1248 10.0007 13.1248Z'
14+
stroke='#384047'
15+
/>
16+
</svg>
17+
);
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import type { ComponentProps } from 'react';
2+
import clsx from 'clsx';
3+
4+
export const IconPaperPlane = ({ className, ...props }: ComponentProps<'svg'>) => (
5+
<svg
6+
stroke='currentColor'
7+
viewBox='0 0 20 20'
8+
{...props}
9+
className={clsx('str-chat__icon--paper-plane', className)}
10+
xmlns='http://www.w3.org/2000/svg'
11+
>
12+
<path
13+
d='M5.00006 9.99996H7.70839M5.00006 9.99996L2.81084 4.05778C2.54981 3.34929 3.29014 2.68668 3.96546 3.02433L16.426 9.25463C17.0402 9.56171 17.0402 10.4382 16.426 10.7453L3.96546 16.9756C3.29014 17.3133 2.54981 16.6506 2.81084 15.9421L5.00006 9.99996Z'
14+
stroke='white'
15+
/>
16+
</svg>
17+
);

src/components/Icons/IconPlus.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { ComponentProps } from 'react';
2+
import clsx from 'clsx';
3+
4+
export const IconPlus = ({ className, ...props }: ComponentProps<'svg'>) => (
5+
<svg
6+
stroke='currentColor'
7+
viewBox='0 0 16 16'
8+
{...props}
9+
className={clsx('str-chat__icon--plus', className)}
10+
xmlns='http://www.w3.org/2000/svg'
11+
>
12+
<path d='M7.625 0.75V7.625M7.625 7.625V14.5M7.625 7.625H0.75M7.625 7.625H14.5' />
13+
</svg>
14+
);

src/components/Icons/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from './IconMicrophone';
2+
export * from './IconPlus';
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.str-chat {
2+
.str-chat__icon--microphone {
3+
stroke-width: 1.5;
4+
stroke-linecap: round;
5+
stroke-linejoin: round;
6+
}
7+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.str-chat {
2+
.str-chat__icon--paper-plane {
3+
stroke-width: 1.5;
4+
stroke-linecap: round;
5+
stroke-linejoin: round;
6+
}
7+
}

0 commit comments

Comments
 (0)