Skip to content

Commit d750d59

Browse files
committed
Updated <Button> docs
1 parent 81a38fa commit d750d59

File tree

2 files changed

+147
-33
lines changed

2 files changed

+147
-33
lines changed

docs/button.md

Lines changed: 146 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -4,40 +4,35 @@ behave as links) in the same uniform manner.
44

55
[Examples](#examples)
66

7-
**Why?** &mdash; Some buttons in our applications, although they look like
8-
regular buttons, should behave as external (to different apps/webpages) or
9-
internal (to different routes inside the app) links. Often, there is a need to
10-
switch between this link-like and the true button behavior as the development
11-
goes. The `<Button>` button component separates button styling from its logic,
12-
helping to switch these behaviors without caring about styling, and update the
13-
styling without caring about functionality.
14-
15-
Under the hood, a `<Button>` is rendered in one of the three ways:
16-
1. When the `<Button>` is disabled it is rendered as `<div>` element with
17-
button content, which allows to style disabled buttons the same way, whether
18-
they are true or buttons or button-like links;
19-
2. Otherwise, if the `<Button>` has `to` property set it is rendered as
20-
[`<Link>`](link-and-navlink.md) (in this case it accepts all other props a
21-
`<Link>` can accept). It helps to properly handle transitions both to external
22-
URLs, and to other routes within the app (these are handled via the React
23-
Router's mechanics, without reloading the app);
24-
3. Otherwise the `<Button>` is rendered as a regular HTML `<button>` (we could
25-
just use the `<Link>` in this case as well, but rendering and handling the
26-
`<button>` is a bit more efficient.
7+
**Why?** &mdash; Sometimes we want a button to behave as an external or internal
8+
link, i.e. either to redirect a visitor to another resource, outside of the app,
9+
or to a different route, without reloading the app. Often there is also a need
10+
to switch between this and the regular button behavior, without changin the
11+
component look and layout. The `<Button>` component separates button styling
12+
from its logic, helping to conveniently handle them independently.
13+
14+
Under the hood, a `<Button>` instance is rendered as:
15+
1. A `<div>` block, when the button is disabled. It helps to ensure exactly the
16+
same style of disabled buttons and button-like links;
17+
2. A [`<Link>`](link-and-navlink.md) component, when `to` property is set. This
18+
takes care about internal and external links.
19+
3. A `<button>` element, otherwise. In principle, our `<Link>` component can
20+
play the button role as well, thus this third case could be avoided, but
21+
rendering true buttons with `<button>` elements is somewhat more efficient.
2722

2823
### Button Properties
29-
- **`active`** &mdash; *Boolean* &mdash; Optional. When *true* the button is
24+
- **`active`** &mdash; *Boolean* &mdash; Optional. When *true*, the button is
3025
rendered in active state, even if it is not active otherwise;
31-
- **`disabled`** &mdash; *Boolean* &mdash; Optional. When *true* the button is
26+
- **`disabled`** &mdash; *Boolean* &mdash; Optional. When *true*, the button is
3227
disabled;
3328
- **`enforceA`** &mdash; *Boolean* &mdash; Optional. When the button is rendered
34-
as `<Link>` this prop enforces it to be rendered as a simple `<a>` element (thus
35-
being treated as an external link);
29+
as `<Link>`, this prop enforces it to be rendered as a simple `<a>` element
30+
(external link);
3631
- **`onClick`** &mdash; *Function* &mdash; Optional. *onClick* event handler;
3732
- **`onMouseDown`** &mdash; *Function* &mdash; Optional. *onMouseDown* event
3833
handler;
3934
- **`opneNewTab`** &mdash; *Boolean* &mdash; Optional. When the button is
40-
rendered as `<Link>` this property tells to open the link in a new tab;
35+
rendered as `<Link>`, this property tells to open the link in a new tab;
4136
- **`replace`** &mdash; *Boolean* &mdash; Optional. When the button is rendered
4237
as `<Link>`, and the URL is internal, this property tells that the new route
4338
should replace the last record in the browser's history, rather than be pushed
@@ -47,9 +42,7 @@ as a new entry into the history stack;
4742
the button. It is supposed to control button size, and although any values can
4843
be used, it is recommended to stick with `xs`, `sm`, `md`, `lg`, and `xl` size
4944
labels, with `md` size being the default, when no `size` property is passed in;
50-
- **`theme`** &mdash; *Object* &mdash; Button theme (we use
51-
[react-css-super-themr](https://www.npmjs.com/package/react-css-super-themr)
52-
to manage default / context / ad-hoc theming of components). This object is
45+
- **`theme`** &mdash; *Object* &mdash; Button theme. This object is
5346
supposed to have the following fields:
5447
- **`button`** &mdash; *String* &mdash; The class to apply to the root element
5548
of the button in all cases;
@@ -64,16 +57,137 @@ supposed to have the following fields:
6457
- Other fields matching acceptable values of the `size` prop. Each of them
6558
will hold the class to additionally apply to the root element of the button,
6659
when the `<size>` value matches;
67-
- **`to`** &mdash; *Object* or *String* &mdash; When specified the button will
60+
- **`to`** &mdash; *Object* or *String* &mdash; When specified, the button will
6861
be rendered as `<Link>` (if non-disabled), and it will point to the specified
6962
URL/location.
7063

7164
### <a name="examples">Examples</a>
72-
Simple button:
73-
```js
65+
First of all, you want to define button theme, here is a good example to start from:
66+
```scss
67+
// theme.scss
68+
69+
/* Base button style (medium size). */
70+
.button {
71+
align-items: center;
72+
background: while;
73+
border: solid 1px black;
74+
color: black;
75+
display: inline-flex;
76+
font: normal 15px arial;
77+
justify-content: center;
78+
min-height: 40px;
79+
margin: 5px;
80+
padding: 5px 23px;
81+
vertical-align: middle;
82+
}
83+
84+
/* Extra styling for the disabled buttons. */
85+
.disabled {
86+
cursor: not-allowed;
87+
opacity: 0.3;
88+
}
89+
90+
/* To ensure that visited button-like links look the same as the non-visited
91+
* ones (as typical buttons should not look different if they used to be clicked
92+
* before). */
93+
.link:visited {
94+
color: black;
95+
font: normal 15px arial;
96+
}
97+
98+
/* .link and .regular classes are applied only to active buttons and button-like
99+
* links. Here we provide visual feedback for button "active", "focus", and
100+
* "hover" states. */
101+
.link,
102+
.regular {
103+
&:focus {
104+
box-shadow: 0 0 2px 1px #cfe6ff;
105+
border-color: #59a7ff;
106+
outline: none;
107+
}
108+
109+
&:hover {
110+
background-image: linear-gradient(to top, #f5f5f5, white 49%, white);
111+
border-color: $tc-gray-40;
112+
}
113+
114+
/* We need both ":active" selector and ".active" class here, if we want to
115+
* properly support the "active" option of the <Button>. */
116+
&.active,
117+
&:active {
118+
background-image: linear-gradient(to bottom, #f5f5f5, white 49%, white);
119+
box-shadow: inset 0 1px 2px 0 rgba(0, 0, 0, 0.2);
120+
border-color: $tc-gray-40;
121+
}
122+
}
123+
124+
/* And a few extra classes to support "xs", "sm", and "lg" button sizes. */
125+
.xs {
126+
font: normal 11px arial;
127+
min-height: 20px;
128+
padding: 1px 13px;
129+
}
130+
131+
.sm {
132+
font: normal 13px arial;
133+
min-height: 30px;
134+
padding: 4px 18px;
135+
}
136+
137+
.lg {
138+
font: normal 17px arial;
139+
min-height: 50px;
140+
padding: 5px 28px;
141+
}
142+
```
143+
144+
You can apply this theme directly to your `<Button>`, but it is more
145+
convenient to use
146+
[react-css-super-themr](https://www.npmjs.com/package/react-css-super-themr)
147+
for management of the button default / context / and ad-hoc theming. To use it,
148+
you should wrap the `<Button>` component with `themr(..)` decorator:
149+
```jsx
150+
// ThemedButton.js
74151
import { Button } from 'topcoder-react-utils';
152+
import { themr } from 'react-css-super-themr';
153+
import theme from './theme.scss';
154+
155+
export default const ThemedButton = themr('ThemedButton', theme)(Button);
156+
```
157+
158+
Now you can use the button in your code in multiple ways:
159+
```js
160+
import React from 'react';
161+
import { ThemeProvider } from 'react-css-super-themr';
162+
import Button from './ThemedButton';
163+
164+
// Some themes we want to use for the ad-hoc and context theming.
165+
import adHocTheme from './adHocStyle.scss';
166+
import contextTheme from './contextTheme';
75167

76168
export default function Example() {
77-
return <Button onClick={() => console.log('Clicked!')}>Click Me!</Button>;
169+
return (
170+
<div>
171+
<Button
172+
// Button with the default theme.
173+
onClick={() => console.log('Clicked!')}
174+
>Click Me!</Button>
175+
176+
<Button
177+
// Button-like link with ad-hoc theming.
178+
theme={adHocTheme}
179+
to="https://www.topcoder.com"
180+
>Click Me!</Button>
181+
182+
<ThemeProvider
183+
theme={{ ThemedButton: contextTheme }}
184+
>
185+
<Button
186+
// Button with context theming.
187+
onClick={() => console.log('Clicked!')}
188+
>Click Me!</Button>
189+
</ThemeProvider>
190+
</div>
191+
);
78192
}
79193
```

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,5 +78,5 @@
7878
"prepublishOnly": "npm run build",
7979
"test": "npm run lint"
8080
},
81-
"version": "0.0.22"
81+
"version": "0.0.23"
8282
}

0 commit comments

Comments
 (0)