├── .babelrc
├── .eslintrc
├── .gitignore
├── .npmignore
├── .travis.yml
├── README.md
├── demo
├── BreadcrumbDemo.jsx
├── ButtonDemo.jsx
├── CardDemo.jsx
├── CheckboxDemo.jsx
├── CommentDemo.jsx
├── ContainerDemo.jsx
├── DividerDemo.jsx
├── FeedDemo.jsx
├── FlagDemo.jsx
├── FormDemo.jsx
├── GridDemo.jsx
├── HeaderDemo.jsx
├── IconDemo.jsx
├── ImageDemo.jsx
├── InputDemo.jsx
├── ItemDemo.jsx
├── LabelDemo.jsx
├── ListDemo.jsx
├── MenuDemo.jsx
├── MessageDemo.jsx
├── ParagraphExample.jsx
├── RailDemo.jsx
├── SegmentDemo.jsx
├── StatisticDemo.jsx
├── StepDemo.jsx
├── TableDemo.jsx
├── bomi.jpg
├── bomi_square.jpg
├── example.css
├── genji.jpg
├── image.png
├── index.js
└── paragraph.png
├── npm-shrinkwrap.json
├── package.json
├── src
├── collections
│ ├── Message.jsx
│ ├── breadcrumb
│ │ ├── Breadcrumb.jsx
│ │ ├── BreadcrumbDivider.jsx
│ │ └── BreadcrumbSection.jsx
│ ├── form
│ │ ├── Form.jsx
│ │ ├── FormField.jsx
│ │ └── FormFieldGroup.jsx
│ ├── grid
│ │ ├── Column.jsx
│ │ ├── Grid.jsx
│ │ └── Row.jsx
│ ├── menu
│ │ ├── Menu.jsx
│ │ └── MenuItem.jsx
│ └── table
│ │ ├── Table.jsx
│ │ ├── TableCell.jsx
│ │ ├── TableFooter.jsx
│ │ ├── TableHeader.jsx
│ │ └── TableRow.jsx
├── common
│ ├── SemanticUiPropTypes.js
│ └── semanticClasses.js
├── elements
│ ├── Container.jsx
│ ├── Divider.jsx
│ ├── Flag.jsx
│ ├── Header.jsx
│ ├── Icon.jsx
│ ├── Input.jsx
│ ├── List.jsx
│ ├── Rail.jsx
│ ├── button
│ │ ├── Button.jsx
│ │ └── ButtonGroup.jsx
│ ├── extra
│ │ ├── Actions.jsx
│ │ ├── Author.jsx
│ │ ├── Avatar.jsx
│ │ ├── Content.jsx
│ │ ├── ContentDescription.jsx
│ │ ├── ContentHeader.jsx
│ │ ├── ContentImages.jsx
│ │ ├── ContentSummary.jsx
│ │ ├── Date.jsx
│ │ ├── Extra.jsx
│ │ ├── Meta.jsx
│ │ ├── MetaData.jsx
│ │ └── Text.jsx
│ ├── image
│ │ ├── Image.jsx
│ │ └── ImageGroup.jsx
│ ├── label
│ │ ├── Label.jsx
│ │ └── LabelGroup.jsx
│ ├── segment
│ │ ├── Segment.jsx
│ │ └── SegmentGroup.jsx
│ └── step
│ │ ├── Step.jsx
│ │ └── StepGroup.jsx
├── index.js
├── modules
│ ├── Checkbox.jsx
│ ├── Modal.jsx
│ ├── ModalActions.jsx
│ ├── ModalContent.jsx
│ └── ModalHeader.jsx
├── util
│ ├── propsToClasses.js
│ ├── spellNumber.js
│ └── string.js
└── views
│ ├── card
│ ├── Card.jsx
│ └── CardGroup.jsx
│ ├── comment
│ ├── Comment.jsx
│ └── CommentGroup.jsx
│ ├── feed
│ ├── Feed.jsx
│ └── FeedEvent.jsx
│ ├── item
│ ├── Item.jsx
│ └── ItemGroup.jsx
│ └── statistic
│ ├── Statistic.jsx
│ └── StatisticGroup.jsx
├── test
├── common
│ └── semanticClasses_spec.js
├── components
│ └── elements
│ │ └── Rail_spec.js
├── test_helper.js
└── util
│ └── string_spec.js
└── webpack.config.dev.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "plugins": ["transform-runtime"],
3 | "presets": ["es2015", "react", "stage-0"]
4 | }
5 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "parser": "babel-eslint",
3 | "env": {
4 | "browser": true,
5 | "node": true
6 | },
7 | "plugins": [
8 | "react"
9 | ],
10 | "ecmaFeatures": {
11 | "jsx": true,
12 | "modules": true
13 | },
14 | "rules": {
15 | "new-cap": 0,
16 | "strict": [2, "global"],
17 | "no-underscore-dangle": 0,
18 | "no-use-before-define": 0,
19 | "eol-last": 0,
20 | "quotes": [2, "single"],
21 | "comma-dangle": 0,
22 | "jsx-quotes": [1, "prefer-single"],
23 | "react/jsx-boolean-value": 1,
24 | "react/jsx-no-undef": 1,
25 | "react/jsx-uses-react": 1,
26 | "react/jsx-uses-vars": 1,
27 | "react/no-did-mount-set-state": 1,
28 | "react/no-did-update-set-state": 1,
29 | "react/no-multi-comp": [1, { "ignoreStateless": true }],
30 | "react/no-unknown-property": 1,
31 | "react/react-in-jsx-scope": 1,
32 | "react/self-closing-comp": 1
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | lib
3 | dist
4 | .tern-project
5 |
6 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src/
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 |
3 | node_js:
4 | - "4.2"
5 | - "5.0"
6 |
7 | cache:
8 | directories:
9 | - node_modules
10 |
11 | sudo: false
12 |
13 | before_install:
14 | - npm install -g npm@3
15 |
16 | before_script:
17 | - npm prune
18 |
19 | script:
20 | - npm test
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-semantic-ui-kit
2 |
3 | [](https://travis-ci.org/shinzui/react-semantic-ui-kit)
4 |
5 | [Semantic UI](http://semantic-ui.com/) rebuilt as React components.
6 |
7 | ## Raison d'être
8 |
9 | - I needed a comprehensive UI component library to use on my side projects.
10 | - I am unsatisfied with [Bootstrap](http://getbootstrap.com/) (including boostrap 4 alpha) and [Foundation for sites](http://foundation.zurb.com/).
11 | - I wanted to learn how to use Semantic UI.
12 |
13 | ## Goals
14 |
15 | - Create components for Semantic UI widgets without using any of Semantic UI's javascript.
16 |
17 | ## Current status
18 |
19 | The project is under heavy development. The goal is to initially implement all components without their javascript behaviors for the [0.2 milestone](https://github.com/shinzui/react-semantic-ui-kit/milestones/0.2).
20 | Please check the demo to see what's already implemented.
21 |
22 | To run the demo:
23 |
24 | $ git clone https://github.com/shinzui/react-semantic-ui-kit.git
25 | $ cd react-semantic-ui-kit && npm install && npm run demo
26 |
27 | Then go to http://localhost:8080/demo
28 |
29 | Alternatively, you can look at the [closed component issues](https://github.com/shinzui/react-semantic-ui-kit/issues?utf8=%E2%9C%93&q=milestone%3A0.2+) which has all the
30 | **fully implemented** Semantic UI components.
31 |
32 | Please note that the API will likely change as I use it on my projects.
33 |
--------------------------------------------------------------------------------
/demo/BreadcrumbDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Segment, Breadcrumb, BreadcrumbDivider, BreadcrumbSection, Divider, Icon } from '../src/index'
4 |
5 | const BreadcrumbDemo = (props) => {
6 | const sizes = ['mini', 'tiny', 'small', 'medium', 'large', 'big', 'huge', 'massive']
7 |
8 | return (
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Search for: properties
34 |
35 |
36 |
37 |
38 |
39 | {sizes.map( size => {
40 | return (
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | )
52 | })}
53 |
54 |
55 |
56 | )
57 | }
58 |
59 | export default BreadcrumbDemo
60 |
--------------------------------------------------------------------------------
/demo/ButtonDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Button, ButtonGroup, Header, Content,
3 | Divider, Segment, Label } from '../src/index'
4 |
5 | import ParagrahExample from './ParagraphExample'
6 |
7 | export default class ButtonDemo extends Component {
8 |
9 | render() {
10 | const colors = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
11 | 'violet', 'purple', 'pink', 'brown', 'grey', 'black']
12 |
13 | const sizes = ['mini', 'tiny', 'small', 'medium', 'large', 'big', 'huge', 'massive']
14 |
15 | return (
16 |
17 |
18 | Simple button
19 | Simple Button
20 |
21 |
22 |
23 | Basic buttons
24 | Basic Button
25 |
26 | {colors.map( color => {
27 | return Basic {color} button
28 | })}
29 |
30 |
31 |
32 | Primary and secondary buttons
33 | Primary Button
34 | Secondary Button
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | Labeled icon
45 |
46 |
47 | Pause
48 |
49 |
50 |
51 |
52 |
53 | One
54 | Two
55 | Three
56 |
57 |
58 |
59 |
60 | Equal width button group
61 |
62 | One
63 | Two
64 | Three
65 |
66 |
67 |
68 |
69 |
70 | One
71 | Two
72 | Three
73 | Four
74 | Five
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 | Cancel
90 |
91 | Save
92 |
93 |
94 |
95 |
96 | Positive button
97 | Negative button
98 |
99 |
100 |
101 | Compact
102 |
103 | Pause
104 |
105 |
106 |
107 | {colors.map( color => {
108 | return {color} button
109 | })}
110 |
111 |
112 |
113 | {colors.map( color => {
114 | return Inverted {color} button
115 | })}
116 |
117 |
118 |
119 | {colors.map( color => {
120 | return Inverted basic {color} button
121 | })}
122 |
123 |
124 |
125 |
126 | One
127 | Two
128 | Three
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 | Active button
140 |
141 | Follow
142 |
143 |
144 |
145 |
146 | Disabled button
147 |
148 | Follow
149 |
150 |
151 |
152 |
153 | Loading buttons
154 | Loading
155 | Loading
156 | Loading
157 | Loading
158 |
159 |
160 |
161 | Fluid buttons
162 | Fluid buttons
163 |
164 |
165 |
166 | Floated buttons
167 |
168 | Right floated
169 | Left floated
170 |
171 |
172 |
173 |
174 |
175 |
176 | Like
177 |
178 | 2049
179 |
180 |
181 | 2049
182 |
183 | Like
184 |
185 |
186 |
187 |
188 | Like
189 |
190 | 2049
191 |
192 |
193 |
194 | Like
195 |
196 | 2049
197 |
198 |
199 |
200 |
201 |
202 | Facebook
203 |
204 |
205 | Twitter
206 |
207 |
208 | Google Plus
209 |
210 |
211 | Instagram
212 |
213 |
214 | LinkedIn
215 |
216 |
217 | YouTube
218 |
219 |
220 | VK
221 |
222 |
223 |
224 |
225 |
226 |
227 | {sizes.map( size => {
228 | return {size} button
229 | })}
230 |
231 |
232 |
233 | Vertical attachment
234 | Top
235 |
236 |
237 |
238 | Bottom
239 |
240 |
241 |
242 | Horizontal attachment
243 | Left
244 | Right
245 |
246 |
247 |
248 | Vertical button group
249 |
250 | Feed
251 | Messages
252 | Events
253 | Photos
254 |
255 |
256 |
257 |
258 | Basic vertical button group
259 |
260 | Feed
261 | Messages
262 | Events
263 | Photos
264 |
265 |
266 |
267 |
268 | Basic button group
269 |
270 | Feed
271 | Messages
272 | Events
273 | Photos
274 |
275 |
276 |
277 |
278 | Animated buttons
279 |
280 | Next
281 |
282 |
283 |
284 | Shop
285 |
286 |
287 |
288 | Sign-up for a pro account
289 | $12.99/month
290 |
291 |
292 |
293 |
294 | Vertical labeled icon buttons
295 |
296 |
297 |
298 | Pause
299 |
300 |
301 |
302 | Play
303 |
304 |
305 |
306 | Shuffle
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 | {sizes.map( size => {
315 | return
316 |
317 | One
318 | Two
319 | Three
320 |
321 |
322 |
323 | })}
324 |
325 |
326 |
327 | )
328 | }
329 | }
330 |
--------------------------------------------------------------------------------
/demo/CardDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Segment, Card, CardGroup, Meta, Image, Grid, Column,
4 | Content, ContentDescription, ContentHeader } from '../src/index'
5 |
6 | import ParagraphExample from './ParagraphExample'
7 |
8 | import bomi from './bomi_square.jpg'
9 | import bomi2 from './bomi.jpg'
10 | import image from './image.png'
11 |
12 | const CardDemo = (props) => {
13 | const colors = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
14 | 'violet', 'purple', 'pink', 'brown', 'grey', 'black']
15 | return (
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | Bomi
24 |
25 | Born in 2015
26 |
27 |
28 | Bomi is a bengal cat.
29 |
30 |
31 |
32 |
33 | 323 Likes
34 |
35 |
36 |
37 |
38 |
39 |
40 | 14h
41 |
42 | Bomi
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | 317 likes
52 |
53 |
54 | 39 comments
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Grouped cards
67 |
68 |
69 |
70 |
71 |
72 |
73 | Bomi
74 |
75 | Born in 2015
76 |
77 |
78 | Bomi is a bengal cat.
79 |
80 |
81 |
82 |
83 | 323 Likes
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 | Bomi
92 |
93 | Born in 2015
94 |
95 |
96 | Bomi is a bengal cat.
97 |
98 |
99 |
100 |
101 | 323 Likes
102 |
103 |
104 |
105 |
106 |
107 |
108 | Fluid Card
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 | Bomi
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | Bomi
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 | Bomi
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 | Centered card
146 |
147 |
148 |
149 |
150 | Bomi
151 |
152 |
153 |
154 |
155 |
156 |
157 | Link card
158 |
159 |
160 |
161 |
162 | Cute Bomi
163 |
164 |
165 |
166 | Bengal cat
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 | Bomi
177 |
178 |
179 |
180 |
181 |
182 |
183 | Colored
184 |
185 | {colors.map( color => {
186 | return (
187 |
188 |
189 |
190 |
191 | {color} card
192 |
193 |
194 |
195 | )
196 | })}
197 |
198 |
199 |
200 |
201 | Column count
202 |
203 | {[1,2,3,4,5,6,7,8].map( (e) => {
204 | return (
205 |
206 |
207 |
208 |
209 | Card
210 |
211 |
212 |
213 | )
214 | })}
215 |
216 |
217 |
218 |
219 | Stackable
220 |
221 | {[1,2,3,4,5,6].map( (e) => {
222 | return (
223 |
224 |
225 |
226 |
227 | Card
228 |
229 |
230 |
231 | )
232 | })}
233 |
234 |
235 |
236 |
237 | Doubling
238 |
239 | {[1,2,3,4,5,6].map( (e) => {
240 | return (
241 |
242 |
243 |
244 |
245 | Card
246 |
247 |
248 |
249 | )
250 | })}
251 |
252 |
253 |
254 |
255 | )
256 | }
257 |
258 | export default CardDemo
259 |
--------------------------------------------------------------------------------
/demo/CheckboxDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Segment, Checkbox } from '../src/index'
4 |
5 | const CheckboxDemo = (props) => {
6 |
7 | return (
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Radio
21 |
22 |
23 |
24 |
25 |
26 | )
27 | }
28 |
29 | export default CheckboxDemo
30 |
--------------------------------------------------------------------------------
/demo/CommentDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Comment, CommentGroup, Segment, Header,
4 | Content, MetaData, Avatar, Date, Author,
5 | Text, Actions, Form, Button } from '../src/index'
6 |
7 | import bomi from './bomi_square.jpg'
8 |
9 | const CommentDemo = (props) => {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Bomi
19 |
20 | Today at 5:42PM
21 |
22 |
23 | React is a great library.
24 |
25 |
26 | Reply
27 |
28 |
29 |
30 |
39 |
40 |
41 |
42 |
43 | Minimal comments
44 |
45 |
46 |
47 |
48 |
49 | Bomi
50 |
51 | Today at 5:42PM
52 |
53 |
54 | React is a great library.
55 |
56 |
57 | Reply
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | Add Reply
67 |
68 |
69 |
70 |
71 |
72 |
73 | Collapsed (hidden) comments
74 |
75 |
76 |
77 |
78 |
79 | Bomi
80 |
81 | Today at 5:42PM
82 |
83 |
84 | React is a great library.
85 |
86 |
87 | Reply
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | Bomi
96 |
97 | Today at 5:42PM
98 |
99 |
100 | React is a great library.
101 |
102 |
103 | Reply
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | Bomi
118 |
119 | Today at 5:42PM
120 |
121 |
122 | React is a great library.
123 |
124 |
125 | Reply
126 |
127 |
128 |
129 |
130 |
131 |
132 | Bomi
133 |
134 | Today at 5:42PM
135 |
136 |
137 | I agree.
138 |
139 |
140 | Reply
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 | Bomi
150 |
151 | Today at 5:42PM
152 |
153 |
154 | Redux is also nice.
155 |
156 |
157 | Reply
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 | Add Reply
167 |
168 |
169 |
170 |
171 |
172 |
173 | )
174 | }
175 |
176 | export default CommentDemo
177 |
--------------------------------------------------------------------------------
/demo/ContainerDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | import { Container, Header, Divider } from '../src/index'
4 |
5 | export default class ContainerDemo extends Component {
6 |
7 | render() {
8 | return(
9 |
10 |
11 |
12 |
13 | Genji was famous and life was secure and peaceful. His ladies had in their several ways made their own lives and were happy.
14 | There was an exception, Tamakazura, who faced a new crisis and was wondering what to do next.
15 |
16 |
17 | She was not as genuinely frightened of him, of course, as she had been of the Higo man; but since few people could possibly know what had happened,
18 | she must keep her disquiet to herself, and her growing sense of isolation. Old enough to know a little of the world, she saw more than ever what a
19 | handicap it was not to have a mother.
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Genji was famous and life was secure and peaceful. His ladies had in their several ways made their own lives and were happy.
29 | There was an exception, Tamakazura, who faced a new crisis and was wondering what to do next.
30 |
31 |
32 | She was not as genuinely frightened of him, of course, as she had been of the Higo man; but since few people could possibly know what had happened,
33 | she must keep her disquiet to herself, and her growing sense of isolation. Old enough to know a little of the world, she saw more than ever what a
34 | handicap it was not to have a mother.
35 |
36 |
37 |
38 |
39 |
40 |
41 | Left aligned
42 |
43 |
44 | Center aligned
45 |
46 |
47 | Right aligned
48 |
49 |
50 | )
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/demo/DividerDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Divider, Segment, Message } from '../src/index'
3 | import { Grid, Row, Column } from '../src/index'
4 |
5 | export default class ButtonDemo extends Component {
6 |
7 | render() {
8 | return (
9 |
10 |
Simple horizontal divider
11 |
12 | Divder Demo
13 |
14 | Divider Demo
15 |
16 |
17 |
Simple vertical divider
18 |
19 |
20 |
21 |
22 | left side
23 |
24 |
25 | left side
26 |
27 |
28 | left side
29 |
30 |
31 | or
32 |
33 |
34 | right side
35 |
36 |
37 | right side
38 |
39 |
40 | right side
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | Header divider
49 |
50 |
51 |
52 | You need to wrap the text inside the header with {""} element otherwise React's inserted span wrappers would break Semantic UI's css.
53 |
54 |
55 | Take a look at issue 2918
56 |
57 |
58 |
59 |
60 | Inverted dividers
61 |
62 | First paragraph
63 |
64 |
65 | Horizontal
66 |
67 |
68 |
69 | Fitted Divider
70 |
71 | Genji was famous and life was secure and peaceful. His ladies had in their several ways made their own lives and were happy.
72 | There was an exception, Tamakazura, who faced a new crisis and was wondering what to do next.
73 |
74 | She was not as genuinely frightened of him, of course, as she had been of the Higo man; but since few people could possibly know what had happened,
75 | she must keep her disquiet to herself, and her growing sense of isolation. Old enough to know a little of the world, she saw more than ever what a
76 | handicap it was not to have a mother.
77 |
78 |
79 |
80 |
81 | You need to wrap the text inside the header with {""} element otherwise React's inserted span wrappers would break Semantic UI's css.
82 |
83 |
84 | Take a look at issue 2918
85 |
86 |
87 |
88 |
89 | Section Divider
90 |
91 | Genji was famous and life was secure and peaceful. His ladies had in their several ways made their own lives and were happy.
92 | There was an exception, Tamakazura, who faced a new crisis and was wondering what to do next.
93 |
94 |
95 | Section two
96 |
97 | She was not as genuinely frightened of him, of course, as she had been of the Higo man; but since few people could possibly know what had happened,
98 | she must keep her disquiet to herself, and her growing sense of isolation. Old enough to know a little of the world, she saw more than ever what a
99 | handicap it was not to have a mother.
100 |
101 |
102 |
103 |
104 | )
105 | }
106 | }
107 |
--------------------------------------------------------------------------------
/demo/FeedDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Feed, FeedEvent, Image, Text,
4 | Content, ContentSummary, ContentImages, Meta,
5 | Date, Segment, Label } from '../src/index'
6 |
7 | import bomi from './bomi_square.jpg'
8 | import bomi2 from './bomi.jpg'
9 |
10 | const FeedDemo = (props) => {
11 | return (
12 |
13 |
14 | Feed
15 |
16 |
17 |
18 |
19 |
20 | Go Joon Hee added you as friend. 1 Hour ago
21 |
22 |
23 |
24 | 23 likes
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | Small feed
34 |
35 |
36 |
37 |
38 |
39 | Go Joon Hee added you as friend. 1 Hour ago
40 |
41 |
42 |
43 | 23 likes
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | Large feed
53 |
54 |
55 |
56 |
57 |
58 | Go Joon Hee added you as friend. 1 Hour ago
59 |
60 |
61 |
62 | 23 likes
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 | 3 days ago
76 | You added Bomi to your favorites group.
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | 3 days ago
88 | You created Bomi's album.
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | 5 days ago
99 | Bomi's created a post.
100 |
101 | I am going to have sibblings soon.
102 |
103 |
104 |
105 |
106 |
107 |
108 | )
109 | }
110 |
111 | export default FeedDemo
112 |
--------------------------------------------------------------------------------
/demo/FlagDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Flag, Segment } from '../src/index'
3 |
4 | export default class FlagDemo extends Component {
5 |
6 | render() {
7 | return (
8 |
9 |
10 | Flags by country name
11 |
12 |
13 |
14 |
15 |
16 | Flags by country code
17 |
18 |
19 |
20 |
21 | )
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/demo/FormDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Form, FormField, FormFieldGroup, Segment, Button, Checkbox } from '../src/index'
3 |
4 | export default class FormDemo extends Component {
5 |
6 | render() {
7 | return (
8 |
9 |
10 |
11 | Field Groups
12 |
13 |
14 |
15 |
16 |
17 | Submit
18 |
19 |
20 |
21 |
22 |
23 | Inline field group
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | Equal width field group
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | Loading form
45 |
46 |
47 |
48 |
49 | Submit
50 |
51 |
52 |
53 |
54 | Small form
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | Large form
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 | Equal width form
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | Inverted form
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 | Disabled fields
98 |
99 |
100 |
101 |
102 | Submit
103 |
104 |
105 |
106 |
107 | Inline fields
108 |
109 |
110 |
111 |
112 | Submit
113 |
114 |
115 |
116 |
117 | Grouped fields
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 | Required fields
135 |
136 |
137 |
138 |
139 | Submit
140 |
141 |
142 |
143 |
144 | Read-only fields
145 |
146 |
147 |
148 |
149 | Submit
150 |
151 |
152 |
153 | )
154 | }
155 | }
156 |
--------------------------------------------------------------------------------
/demo/GridDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | import { Segment, Header, Grid, Column, Row } from '../src/index'
4 | import ParagraphExample from './ParagraphExample'
5 | import image from './image.png'
6 |
7 | export default class GridDemo extends Component {
8 |
9 | render() {
10 | return (
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Relaxed grid
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | Padded grid
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 | Clearing content
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | Centered content
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 | Automatic column count
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 | Doubling
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 | Containers
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 | Stackable grid
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 | Manual tweaks
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | Internally celled grids
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
227 | Left floated right aligned column
228 |
229 |
230 |
231 |
232 | Right floated left aligned column
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 | Right aligned grid
241 |
242 |
243 |
244 |
245 |
246 | Text alignment
247 |
248 |
249 |
250 | Center aligned row
251 |
252 |
253 |
254 |
255 | Center aligned row
256 |
257 |
258 |
259 |
260 |
261 |
262 | Left aligned row
263 |
264 |
265 |
266 |
267 | Left aligned row
268 |
269 |
270 |
271 |
272 |
273 |
274 | Right aligned row
275 |
276 |
277 |
278 |
279 | Right aligned row
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 | Reverse order
288 |
289 | First
290 | Second
291 | Third
292 |
293 |
294 |
295 |
296 |
297 | Colored columns
298 |
299 |
300 |
301 | blue
302 |
303 |
304 | red
305 |
306 |
307 |
308 |
309 | green
310 |
311 |
312 |
313 | orange
314 | purple
315 |
316 |
317 |
318 |
319 | )
320 | }
321 | }
322 |
--------------------------------------------------------------------------------
/demo/HeaderDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Image, Header, Segment } from '../src/index'
3 |
4 | import bomi from './bomi.jpg'
5 |
6 | export default class HeaderDemo extends Component {
7 |
8 | render() {
9 | return (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | Icon header
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 | Some content
52 |
53 |
54 |
55 |
56 |
57 |
58 | Some content
59 |
60 |
61 |
62 |
63 | Top Attached header
64 |
65 |
66 |
67 | Attached segment
68 |
69 |
70 |
71 | Attached header
72 |
73 |
74 |
75 | Attached segment
76 |
77 |
78 |
79 | Bottom attached header
80 |
81 |
82 |
83 |
84 | Right aligned header
85 |
86 |
87 | Center aligned header
88 |
89 |
90 | Left aligned header
91 |
92 |
93 | A long header that is justified
94 |
95 |
96 |
97 |
98 |
99 | Right floated header
100 |
101 |
102 | Left floated header
103 |
104 |
105 |
106 |
107 |
108 | Inverted header
109 |
110 |
111 |
112 |
113 | )
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/demo/IconDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Segment, Icon, Grid, Column } from '../src/index'
4 | import { splitAndLowerCamelCase } from '../src/util/string'
5 |
6 | const IconDemo = (props) => {
7 | const webIcons1 = [
8 | 'at', 'browser', 'bug', 'calendar', {type: 'calendar', outline: true, key: 'calendarOutline'},
9 | 'cloud', 'code', 'comments', {type: 'comments', outline: true, key: 'commentsOutline'},
10 | 'comment', {type: 'comment', outline: true, key: 'commentOutline'},
11 | 'copyright', 'dashboard', 'dropdown', 'external',
12 | {type: 'external', square: true, key: 'externalSquare'},
13 | 'eyedropper', 'feed', 'find', 'heartbeat', 'history',
14 | 'home', 'idea', 'inbox', 'lab', 'mail',
15 | {type: 'mail', outline: true, key: 'mailOuline'}, {type: 'mail', square: true, key: 'mailSquare'},
16 | 'map', 'options', 'paintBrush', 'payment', 'phone', {type: 'phone', square: true, key: 'phoneSquare'},
17 | 'privacy', 'protect', 'search', 'setting', 'settings', 'shop', 'sidebar', 'signal', 'sitemap', 'tag',
18 | 'tags', 'tasks', 'terminal', 'textTelephone', 'ticket', 'trophy', 'wifi'
19 | ]
20 |
21 | const userIcons = [ 'adjust', 'addUser', 'addToCart', 'archive', 'ban',
22 | 'bookmark', 'call',{type: 'call', square: true, key: 'callSquare'}, 'cloudDownload', 'cloudUpload',
23 | 'compress', 'configure', 'download', 'edit', 'erase', 'exchange', 'externalShare', 'expand',
24 | 'filter', 'flag', {type: 'flag', outline: true, key:'flagOutline'}, 'forwardMail', 'hide',
25 | 'inCart', 'lock', 'pin', 'print', 'random', 'recycle', 'refresh', 'removeBookmark', 'removeUser',
26 | 'repeat', 'replyAll', 'reply', 'retweet', 'send', {type: 'send', outline: true, key: 'sendOutline'},
27 | 'shareAlternate', {type: 'shareAlternate', square: true, key:'shareAlternateS'} , 'share',
28 | {type: 'share', square: true, key: 'shareSquare'}, 'signIn', 'signOut',
29 | 'theme', 'translate', 'undo', 'unhide', 'unlockAlternate', 'unlock', 'upload', 'wait',
30 | 'wizard', 'write', {type: 'write', square: true, key: 'writeSquare'}]
31 |
32 | const messageIcons = ['announcement', 'birthday', 'flag', 'help', {type: 'help', circle: true, key: 'helpCircle'},
33 | 'info', {type: 'info', circle: true, key: 'infoCircle'}, 'warning', {type: 'warning', circle: true, key: 'warningCircle'},
34 | 'warningSign']
35 |
36 | const userTypesIcons = ['child', 'doctor', 'handicap', 'spy', 'student', 'user', 'users']
37 |
38 | const iconName = (type) => {
39 | const classes = splitAndLowerCamelCase(type)
40 | return classes.charAt(0).toUpperCase() + classes.slice(1)
41 | }
42 |
43 | const renderIcon = (icon) => {
44 | if(typeof icon === 'string') {
45 | return {iconName(icon)}
46 | } else {
47 | let suffix = ''
48 | if(icon.square) suffix = ' square'
49 | if(icon.circle) suffix = ' circle'
50 | if(icon.outline) suffix = suffix + ' outline'
51 |
52 | return
53 | {iconName(icon.type) + suffix}
54 |
55 | }
56 | }
57 |
58 | return (
59 |
60 |
61 | Web content
62 |
63 |
64 | Alarm
65 |
66 |
67 | Alarm outline
68 |
69 |
70 | Alarm slash
71 |
72 |
73 | Alarm outline
74 |
75 | {webIcons1.map(renderIcon)}
76 |
77 |
78 |
79 |
80 | User actions
81 |
82 | {userIcons.map(renderIcon)}
83 |
84 |
85 |
86 |
87 | Message
88 |
89 | {messageIcons.map(renderIcon)}
90 |
91 |
92 |
93 |
94 | User types
95 |
96 | {userTypesIcons.map(renderIcon)}
97 |
98 |
99 |
100 | )
101 | }
102 |
103 | export default IconDemo
104 |
--------------------------------------------------------------------------------
/demo/ImageDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Image , ImageGroup, Segment, Divider } from '../src/index'
3 | import { Grid, Row, Column } from '../src/index'
4 |
5 | import bomi from './bomi.jpg'
6 | import genji from './genji.jpg'
7 |
8 | export default class ImageDemo extends Component {
9 |
10 | render() {
11 | return (
12 |
13 |
14 | Centered Image
15 |
16 |
17 |
18 | Circular Image
19 |
20 |
21 |
22 | Rounded Image
23 |
24 |
25 |
26 |
27 | Fluid Image
28 |
29 |
30 |
31 |
32 |
33 |
34 | The days went by and the thunder and rain continued. What was Genji to do? People would laugh if, in this extremity, out of favor at court, he were to return to the city. Should he then seek a mountain retreat?
35 | But if it were to be noised about that a storm had driven him away, then he would cut a ridiculous figure in history.
36 | His dreams were haunted by that same apparition. Messages from the city almost entirely ceased coming as the days went by without a break in the storms.
37 | Might he end his days at Suma? No one was likely to come calling in these tempests.
38 |
39 |
40 |
41 | A messenger did come from Murasaki, a sad, sodden creature. Had they passed in the street, Genji would scarcely have known whether he was man or beast, and of course would not have thought of inviting him to come near. Now the man brought a surge of pleasure
42 | and affection — though Genji could not help asking himself whether the storm had weakened his moorings.
43 |
44 |
45 | Murasaki’s letter, long and melancholy, said in part: “The terrifying deluge goes on without a break, day after day. Even the skies are closed off, and I am denied the comfort of gazing in your direction.
46 |
47 |
48 |
49 |
50 |
51 | Top aligned
52 |
53 |
54 |
55 |
56 | Middle aligned
57 |
58 |
59 |
60 | Bottom aligned
61 |
62 |
63 |
64 |
65 | Disabled Image
66 |
67 |
68 |
69 |
70 |
71 | Image Group
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | )
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/demo/InputDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Input, Segment, Button,
4 | Header, Divider, Label } from '../src/index'
5 |
6 | const InputDemo = (props) => {
7 | const sizes = ['mini', 'small', 'medium', 'large', 'big', 'huge', 'massive']
8 |
9 | return (
10 |
147 | )
148 | }
149 |
150 | export default InputDemo
151 |
--------------------------------------------------------------------------------
/demo/ItemDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { ItemGroup, Image, Item, Segment, Extra, Label, Button,
3 | Content, ContentHeader, Meta, ContentDescription } from '../src/index'
4 |
5 | import ParagraphExample from './ParagraphExample'
6 |
7 | import bomi from './bomi.jpg'
8 | import image from './image.png'
9 |
10 | export default class ItemDemo extends Component {
11 |
12 | render() {
13 | return (
14 |
15 |
16 |
17 | -
18 |
19 |
20 |
21 |
22 | -
23 |
24 |
25 |
26 |
27 | -
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | Link item
37 |
38 | -
39 |
40 |
41 |
42 | Bomi
43 |
44 |
45 | Some description
46 |
47 |
48 |
49 | -
50 |
51 |
52 |
53 | Bomi
54 |
55 |
56 | Some description
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 | Divided item
65 |
66 | -
67 |
68 |
69 | Sulawesi, Toarco Peaberry
70 | Indonesia
71 |
72 |
73 |
74 |
75 | Limited
76 |
77 |
78 |
79 | -
80 |
81 |
82 | Yetatebe, Shakisso
83 | Ethiopia
84 |
85 |
86 |
87 |
88 |
89 | Buy coffee
90 |
91 | Limited
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | Relaxed
100 |
101 | -
102 |
103 |
104 |
105 | Yojimbo
106 |
107 |
108 |
109 | -
110 |
111 |
112 |
113 | Rashomon
114 |
115 |
116 |
117 | -
118 |
119 |
120 |
121 | Seven Samurai
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 | Link Item
130 |
131 | -
132 |
133 |
134 |
135 | Yojimbo
136 |
137 |
138 |
139 |
140 |
141 |
142 | -
143 |
144 |
145 |
146 | Rashomon
147 |
148 |
149 |
150 |
151 |
152 |
153 | -
154 |
155 |
156 |
157 | Seven Samurai
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 | Vertical alignment
169 |
170 | -
171 |
172 |
173 |
174 | Yojimbo
175 |
176 |
177 |
178 | -
179 |
180 |
181 |
182 | Rashomon
183 |
184 |
185 |
186 | -
187 |
188 |
189 |
190 | Seven Samurai
191 |
192 |
193 |
194 |
195 |
196 |
197 | )
198 | }
199 | }
200 |
--------------------------------------------------------------------------------
/demo/LabelDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Label , LabelGroup, List, ListItem,
3 | Grid, Column, Row, Menu, MenuItem,
4 | Header, Segment, Image } from '../src/index'
5 |
6 | import bomi from './bomi.jpg'
7 | import image from './image.png'
8 | import paragraph from './paragraph.png'
9 |
10 | export default class LabelDemo extends Component {
11 |
12 | render() {
13 | const colors = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
14 | 'violet', 'purple', 'pink', 'brown', 'grey', 'black']
15 | const sizes = ['mini', 'tiny', 'small', 'medium', 'large', 'big', 'huge', 'massive']
16 |
17 | return (
18 |
19 |
20 | Pointing label Some text.
21 | Bottom pointing label
22 | Left pointing label
23 | Top pointing label
24 |
25 |
26 | Left pointing red basic label
27 |
28 |
29 |
30 |
31 |
32 | Bomi
33 |
34 |
35 |
36 |
37 |
38 |
39 | Node
40 | Hapi
41 |
42 |
43 | Ruby
44 | Rails
45 |
46 |
47 |
48 |
49 | Tags
50 | JavaScript
51 | React
52 | ES2015
53 |
54 |
55 | Circular
56 | Circular Label
57 | 1
58 | 2
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | React
85 |
86 |
87 |
88 |
89 |
90 |
91 | Overview
92 | Account details
93 |
94 | Lorem ipsum is a pseudo-Latin text used in web design, typography, layout, and printing in place of English to emphasise design elements over content.
95 | It's also called placeholder (or filler) text. It's a convenient tool for mock-ups.
96 |
97 | Community
98 | User reviews
99 |
100 | It helps to outline the visual elements of a document or presentation, eg typography, font, or layout.
101 | Lorem ipsum is mostly a part of a Latin text by the classical author and philosopher Cicero.
102 |
103 |
104 |
105 |
106 |
107 | Overview
108 |
109 | Its words and letters have been changed by addition or removal, so to deliberately render its content nonsensical;
110 | it's not genuine, correct, or comprehensible Latin anymore.
111 |
112 | Conclusion
113 |
114 | While lorem ipsum's still resembles classical Latin, it actually has no meaning whatsoever. As Cicero's text doesn't contain the letters K, W, or Z, alien to latin,
115 | these, and others are often inserted randomly to mimic the typographic appearence of European languages, as are digraphs not to be found in the original.
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 | Floating label
124 |
125 |
126 |
127 | Messages
128 | 23
129 |
130 |
131 | Friends
132 | 7
133 |
134 |
135 |
136 |
137 |
138 |
139 | Attached labels
140 |
141 |
142 |
143 |
144 |
145 | Top
146 |
147 |
148 |
149 |
150 |
151 | Bottom
152 |
153 |
154 |
155 |
156 |
157 | Top right
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 | Top left
166 |
167 |
168 |
169 |
170 |
171 | Bottom right
172 |
173 |
174 |
175 |
176 |
177 | Bottom left
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 | {sizes.map( size => {
189 | return {size} label
190 | })}
191 |
192 |
193 |
194 |
195 |
196 | {colors.map( color => {
197 | return {color} label
198 | })}
199 |
200 |
201 |
202 |
203 |
204 | First
205 | Second
206 | Third
207 |
208 |
209 |
210 |
211 |
212 |
213 | First
214 | Second
215 | Third
216 |
217 |
218 |
219 |
220 |
221 |
222 | javascript
223 | node
224 | react
225 |
226 |
227 |
228 |
229 |
230 |
231 | 1
232 | 2
233 | 3
234 |
235 |
236 |
237 | )
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/demo/MessageDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | import { Segment, Message } from '../src/index'
4 |
5 | const MessageDemo = (props) => {
6 | const colors = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
7 | 'violet', 'purple', 'pink', 'brown', 'grey', 'black']
8 |
9 | const sizes = ['small', 'large', 'huge', 'massive']
10 |
11 | return (
12 |
13 |
14 |
15 |
16 | A basic message
17 |
18 |
19 | We are going to be closed for the holiday.
20 |
21 |
22 |
23 |
24 |
25 | New Features
26 |
27 | You can now create swimlanes
28 | You can upload attachments to cards
29 |
30 |
31 |
32 |
33 |
34 | Icon message
35 |
36 |
37 |
38 |
Do you need help with continuous improvement?
39 |
Join our mailing list and get tips from the best practitioners.
40 |
41 |
42 |
43 |
44 |
45 | Dismissible message
46 |
47 | New Features
48 |
49 | You can now create swimlanes
50 | You can upload attachments to cards
51 |
52 |
53 |
54 |
55 |
56 | Floating message
57 |
58 | New Features
59 |
60 | You can now create swimlanes
61 | You can upload attachments to cards
62 |
63 |
64 |
65 |
66 |
67 |
68 | A compact message
69 |
70 |
71 |
72 |
73 |
74 | This is a top attached message
75 |
76 |
77 |
78 | Some content
79 |
80 |
81 |
82 | Bottom attached warning message
83 |
84 |
85 |
86 |
87 | Warning message
88 |
89 |
90 | You must register in order to view this.
91 |
92 | Register, then try again.
93 |
94 |
95 |
96 |
97 | Info message
98 |
99 | New Features
100 |
101 | You can now create swimlanes
102 | You can upload attachments to cards
103 |
104 |
105 |
106 |
107 |
108 | Positive message
109 |
110 |
111 | You are eligible for a 30% discount
112 |
113 | Visit our deals page now.
114 |
115 |
116 |
117 |
118 | Success message
119 |
120 | You've successfully registered
121 | You can now enjoy all the benefits of membership.
122 |
123 |
124 |
125 |
126 | Negative message
127 |
128 | We're sorry you're not eligible for registration
129 | Please apply again when you meet the requirement
130 |
131 |
132 |
133 |
134 | Error message
135 |
136 | Please fix the following errors:
137 |
138 | Your password is too short.
139 | Your username is already taken.
140 |
141 |
142 |
143 |
144 |
145 | Colored messages
146 |
147 | {colors.map( color => {
148 | return {color} message
149 | })}
150 |
151 |
152 |
153 | Sizes
154 |
155 | {sizes.map( size => {
156 | return {size} message
157 | })}
158 |
159 |
160 |
161 |
162 |
163 | )
164 | }
165 |
166 | export default MessageDemo
167 |
--------------------------------------------------------------------------------
/demo/ParagraphExample.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Image } from '../src/index'
4 |
5 | import paragraph from './paragraph.png'
6 |
7 | const ParagraphDemo = (props) => {
8 | return
9 | }
10 |
11 | export default ParagraphDemo
12 |
--------------------------------------------------------------------------------
/demo/RailDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Rail, Segment } from '../src/index'
3 |
4 | export default class RailDemo extends Component {
5 |
6 | render() {
7 | return (
8 |
9 |
10 |
11 |
12 | Right Rail
13 |
14 |
15 |
16 | Main content.
17 |
18 |
19 |
20 |
21 |
22 |
23 | A close Rail
24 |
25 |
26 |
27 | Main content.
28 |
29 |
30 |
31 |
32 |
33 |
34 | A right dividing Rail.
35 |
36 |
37 |
38 | Content.
39 |
40 |
41 |
42 |
43 |
44 |
45 | Left internal rail.
46 |
47 |
48 |
49 |
50 | Right internal rail.
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | An attached Rail.
59 |
60 |
61 |
62 |
63 | Main content.
64 |
65 |
66 |
67 |
68 | )
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/demo/SegmentDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 |
3 | import { Segment, SegmentGroup, Header, Image, Button } from '../src/index'
4 |
5 | import paragraph from './paragraph.png'
6 |
7 | const SegmentDemo = (props) => {
8 | const colors = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
9 | 'violet', 'purple', 'pink', 'brown', 'grey', 'black']
10 |
11 | return (
12 |
13 |
14 | A raised segment
15 |
16 |
17 |
18 | A stacked segment
19 |
20 |
21 |
22 |
23 | A piled segment
24 |
25 |
26 |
27 | Some text for the piled segment
28 |
29 |
30 |
31 |
32 | A disabled segment
33 |
34 |
35 |
36 | A loading segment
37 |
38 |
39 |
40 | An inverted segment
41 |
42 |
43 |
44 | Top attached segment
45 |
46 |
47 | Segment attached on both sides
48 |
49 |
50 | Bottom attached segment
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 | {colors.map( color => {
63 | return
{color} segment
64 | })}
65 |
66 | {colors.map( color => {
67 | return
Inverted {color} segment
68 | })}
69 |
70 |
71 | Compact segment
72 |
73 |
74 |
75 | Secondary segment
76 |
77 |
78 |
79 | Tertiary segment
80 |
81 |
82 |
83 | Inverted segment
84 |
85 |
86 | Inverted secondary segment
87 |
88 |
89 |
90 | Inveretd tertiary segment
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 | Floated
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | Right floated
107 |
108 |
109 |
110 |
111 | Left floated
112 |
113 |
114 |
115 |
116 |
117 |
118 | Right aligned
119 |
120 |
121 |
122 |
123 | Center aligned
124 |
125 |
126 |
127 |
128 | Left aligned
129 |
130 |
131 |
132 |
133 |
134 |
135 | Basic segment without formatting.
136 |
137 |
138 |
139 |
140 |
141 |
142 | Compact segment in group
143 |
144 |
145 | Compact segment in group
146 |
147 |
148 |
149 |
150 |
151 | First segment in a group
152 |
153 |
154 | Second segment in a group
155 |
156 |
157 | Third segment in a group
158 |
159 |
160 |
161 |
162 |
163 | First segment in a raised group
164 |
165 |
166 | Second segment in a group
167 |
168 |
169 | Third segment in a group
170 |
171 |
172 |
173 |
174 |
175 | First segment in a stacked group
176 |
177 |
178 | Second segment in a group
179 |
180 |
181 | Third segment in a group
182 |
183 |
184 |
185 |
186 |
187 | First segment in a piled group
188 |
189 |
190 | Second segment in a group
191 |
192 |
193 | Third segment in a group
194 |
195 |
196 |
197 |
198 |
199 | First segment in a horizontal group
200 |
201 |
202 | Second segment in a group
203 |
204 |
205 | Third segment in a group
206 |
207 |
208 |
209 |
210 |
211 | Top
212 |
213 |
214 |
215 | Nested top
216 |
217 |
218 | Nested middle
219 |
220 |
221 | Nested bottom
222 |
223 |
224 |
225 |
226 |
227 | )
228 | }
229 |
230 | export default SegmentDemo
231 |
--------------------------------------------------------------------------------
/demo/StatisticDemo.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import { Statistic, Segment, StatisticGroup } from '../src/index'
3 |
4 | export default class StatisticDemo extends Component {
5 |
6 | render() {
7 | const colors = ['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
8 | 'violet', 'purple', 'pink', 'brown', 'grey', 'black']
9 | const sizes = ['mini', 'tiny', 'small', 'medium', 'large', 'big', 'huge', 'massive']
10 |
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Statistic group
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Horizontal statistic
31 |
32 |
33 |
34 |
35 | Horizontal statistic group
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 | Evenly divided
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | Text value
54 |
55 |
56 |
57 |
58 | Color
59 |
60 | {colors.map( color => {
61 | return
62 | })}
63 |
64 |
65 |
66 |
67 | Color
68 | {colors.map( color => {
69 | return
70 | })}
71 |
72 |
73 |
74 | Size
75 | {sizes.map( size => {
76 | return
77 | })}
78 |
79 |
80 |
81 | Horizontal sizes
82 | {sizes.map( size => {
83 | return
84 | })}
85 |
86 |
87 | )
88 | }
89 | }
90 |
--------------------------------------------------------------------------------
/demo/StepDemo.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import { Segment, Divider, Image,
4 | Grid, Column,
5 | Step, StepGroup } from '../src/index'
6 |
7 | import paragraph from './paragraph.png'
8 |
9 | const StepDemo = (props) => {
10 | return (
11 |
12 |
13 | Single step
14 |
15 |
16 | Step
17 |
18 |
19 |
20 |
21 | Group of steps
22 |
23 |
24 |
25 |
26 |
Registration
27 |
email and password
28 |
29 |
30 |
31 |
32 |
Profile
33 |
name and contact
34 |
35 |
36 |
37 |
38 |
Preferences
39 |
default settings
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
Registration
50 |
email and password
51 |
52 |
53 |
54 |
55 |
Profile
56 |
name and contact
57 |
58 |
59 |
60 |
61 |
Preferences
62 |
default settings
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
Registration
73 |
email and password
74 |
75 |
76 |
77 |
78 |
Profile
79 |
name and contact
80 |
81 |
82 |
83 |
84 |
Preferences
85 |
default settings
86 |
87 |
88 |
89 |
90 |
91 |
92 | Step States
93 |
94 |
95 |
96 |
97 |
Preferences
98 |
default settings
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
Preferences
109 |
default settings
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
Preferences
121 |
default settings
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
Preferences
135 |
default settings
136 |
137 |
138 |
139 |
140 |
141 |
Preferences
142 |
default settings
143 |
144 |
145 |
146 |
147 |
148 | Fluid Step
149 |
150 |
151 |
152 |
153 |
154 | Stackable on tablets
155 |
156 |
157 |
158 |
Registration
159 |
email and password
160 |
161 |
162 |
163 |
164 |
Profile
165 |
name and contact
166 |
167 |
168 |
169 |
170 |
Preferences
171 |
default settings
172 |
173 |
174 |
175 |
176 |
177 |
178 | Evenly divided
179 |
180 |
181 |
182 |
Registration
183 |
email and password
184 |
185 |
186 |
187 |
188 |
Profile
189 |
name and contact
190 |
191 |
192 |
193 |
194 |
Preferences
195 |
default settings
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
Registration
205 |
email and password
206 |
207 |
208 |
209 |
210 |
Profile
211 |
name and contact
212 |
213 |
214 |
215 |
216 |
Preferences
217 |
default settings
218 |
219 |
220 |
221 |
222 |
223 |
Team
224 |
team settings
225 |
226 |
227 |
228 |
229 |
230 |
231 | Attached
232 |
233 |
234 |
235 |
Registration
236 |
email and password
237 |
238 |
239 |
240 |
241 |
Profile
242 |
name and contact
243 |
244 |
245 |
246 |
247 |
Preferences
248 |
default settings
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
Registration
261 |
email and password
262 |
263 |
264 |
265 |
266 |
Profile
267 |
name and contact
268 |
269 |
270 |
271 |
272 |
Preferences
273 |
default settings
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 | Sizes
282 |
283 |
284 |
285 |
286 |
Preferences
287 |
default settings
288 |
289 |
290 |
291 |
292 |
293 |
Preferences
294 |
default settings
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
Preferences
305 |
default settings
306 |
307 |
308 |
309 |
310 |
311 |
Preferences
312 |
default settings
313 |
314 |
315 |
316 |
317 |
318 | )
319 | }
320 |
321 | export default StepDemo
322 |
--------------------------------------------------------------------------------
/demo/bomi.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shinzui/react-semantic-ui-kit/151e3540aa5aa1f2b29237c6d101403e995b5086/demo/bomi.jpg
--------------------------------------------------------------------------------
/demo/bomi_square.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shinzui/react-semantic-ui-kit/151e3540aa5aa1f2b29237c6d101403e995b5086/demo/bomi_square.jpg
--------------------------------------------------------------------------------
/demo/example.css:
--------------------------------------------------------------------------------
1 | .examplePage {
2 | margin-top: 20px;
3 | }
4 |
5 | .gridExample .grid:before {
6 | position: absolute;
7 | top: 1rem;
8 | left: 1rem;
9 | background-color: #fafafa;
10 | content: "";
11 | width: calc(100% - 2rem);
12 | height: calc(100% - 2rem);
13 | box-shadow: 0px 0px 0px 1px #dddddd inset;
14 | }
15 |
16 | .gridExample .grid {
17 | position: relative;
18 | }
19 | .gridExample .row {
20 | position: relative;
21 | }
22 | .gridExample .grid > .column {
23 | position: relative;
24 | z-index: 11;
25 | }
26 |
27 | .gridExample .grid .column:not(.grid):not(.row):after {
28 | background-color: rgba(86, 61, 124, .1);
29 | -webkit-box-shadow: 0px 0px 0px 1px rgba(86, 61, 124, 0.2) inset;
30 | box-shadow: 0px 0px 0px 1px rgba(86, 61, 124, 0.2) inset;
31 | content: "";
32 | display: block;
33 | min-height: 50px;
34 | }
35 |
36 | .iconExample .grid {
37 | text-align: left;
38 | }
39 |
40 | .iconExample .grid > .column {
41 | opacity: 0.7;
42 | text-align: center;
43 | color: #777777;
44 | align-items: center;
45 | }
46 |
47 | .iconExample .column .icon {
48 | opacity: 1;
49 | height: 1em;
50 | display: block;
51 | color: #333333;
52 | font-size: 2em;
53 | margin: 0em auto 0.25em;
54 | }
55 |
--------------------------------------------------------------------------------
/demo/genji.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shinzui/react-semantic-ui-kit/151e3540aa5aa1f2b29237c6d101403e995b5086/demo/genji.jpg
--------------------------------------------------------------------------------
/demo/image.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shinzui/react-semantic-ui-kit/151e3540aa5aa1f2b29237c6d101403e995b5086/demo/image.png
--------------------------------------------------------------------------------
/demo/index.js:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react'
2 | import ReactDOM from 'react-dom'
3 |
4 | import 'semantic-ui-css/semantic.css'
5 |
6 | import { Container, Message, Grid, Column, Menu, MenuItem } from '../src/index'
7 | import FormDemo from './FormDemo'
8 | import ButtonDemo from './ButtonDemo'
9 | import DividerDemo from './DividerDemo'
10 | import ImageDemo from './ImageDemo'
11 | import LabelDemo from './LabelDemo'
12 | import MessageDemo from './MessageDemo'
13 | import StatisticDemo from './StatisticDemo'
14 | import ItemDemo from './ItemDemo'
15 | import HeaderDemo from './HeaderDemo'
16 | import ListDemo from './ListDemo'
17 | import RailDemo from './RailDemo'
18 | import SegmentDemo from './SegmentDemo'
19 | import FlagDemo from './FlagDemo'
20 | import ContainerDemo from './ContainerDemo'
21 | import GridDemo from './GridDemo'
22 | import InputDemo from './InputDemo'
23 | import StepDemo from './StepDemo'
24 | import TableDemo from './TableDemo'
25 | import CardDemo from './CardDemo'
26 | import CheckboxDemo from './CheckboxDemo'
27 | import MenuDemo from './MenuDemo'
28 | import FeedDemo from './FeedDemo'
29 | import CommentDemo from './CommentDemo'
30 | import IconDemo from './IconDemo'
31 | import BreadcrumbDemo from './BreadcrumbDemo'
32 |
33 | import './example.css'
34 |
35 | const root = document.createElement('div')
36 | root.classList.add('examplePage')
37 | document.body.appendChild(root)
38 |
39 | class Page extends Component {
40 |
41 | constructor(props) {
42 | super(props)
43 | this.onHashChange = ::this.onHashChange
44 | }
45 |
46 | state = {
47 | Page: undefined
48 | }
49 |
50 | componentDidMount() {
51 | this.setPage()
52 | window.addEventListener('hashchange', this.onHashChange)
53 | }
54 |
55 | setPage() {
56 | const pages = {
57 | forms: FormDemo,
58 | buttons: ButtonDemo,
59 | images: ImageDemo,
60 | divider: DividerDemo,
61 | labels: LabelDemo,
62 | messages: MessageDemo,
63 | statistic: StatisticDemo,
64 | item: ItemDemo,
65 | header: HeaderDemo,
66 | list: ListDemo,
67 | rail: RailDemo,
68 | segment: SegmentDemo,
69 | flag: FlagDemo,
70 | container: ContainerDemo,
71 | grid: GridDemo,
72 | input: InputDemo,
73 | step: StepDemo,
74 | table: TableDemo,
75 | card: CardDemo,
76 | checkbox: CheckboxDemo,
77 | menu: MenuDemo,
78 | feed: FeedDemo,
79 | comment: CommentDemo,
80 | icon: IconDemo,
81 | breadcrumb: BreadcrumbDemo
82 | }
83 |
84 | let hash = window.location.hash
85 | let newPage = pages[hash.substring(1)]
86 |
87 | if(newPage) {
88 | this.setState({ Page: newPage})
89 | } else {
90 | this.setState({ Page: undefined })
91 | }
92 | }
93 |
94 | onHashChange() {
95 | this.setPage()
96 | }
97 |
98 | render() {
99 | const { Page } = this.state
100 |
101 | const content = Page ? : undefined
102 |
103 | const items = ['forms', 'input', 'buttons', 'images', 'labels',
104 | 'messages', 'divider', 'statistic', 'item', 'header',
105 | 'list', 'rail', 'segment', 'flag', 'container', 'grid', 'step',
106 | 'table', 'card', 'checkbox', 'menu', 'feed', 'comment', 'icon',
107 | 'breadcrumb']
108 |
109 | return (
110 |
111 |
112 |
113 | {items.map( item => {item.charAt(0).toUpperCase() + item.slice(1)} )}
114 |
115 |
116 |
117 | {content}
118 |
119 |
120 | )
121 | }
122 | }
123 |
124 | ReactDOM.render( , root)
125 |
--------------------------------------------------------------------------------
/demo/paragraph.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/shinzui/react-semantic-ui-kit/151e3540aa5aa1f2b29237c6d101403e995b5086/demo/paragraph.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-semantic-ui-kit",
3 | "version": "0.1.9",
4 | "description": "Semantic UI components built with React",
5 | "main": "lib/index.js",
6 | "files": [
7 | "lib"
8 | ],
9 | "scripts": {
10 | "compile": "babel -d lib/ src/",
11 | "prepublish": "npm run compile",
12 | "demo": "webpack-dev-server --config webpack.config.dev.js",
13 | "test": "mocha --compilers js:babel-core/register --require ./test/test_helper.js 'test/**/*.@(js|jsx)'",
14 | "test:watch": "npm run test -- --watch",
15 | "preversion": "npm test",
16 | "version": "npm run compile",
17 | "postversion": "git push && git push --tags && npm publish"
18 | },
19 | "repository": {
20 | "type": "git",
21 | "url": "https://github.com/shinzui/react-semantic-ui-kit.git"
22 | },
23 | "keywords": [
24 | "semantic-ui",
25 | "react"
26 | ],
27 | "author": "Nadeem Bitar (https://productatelier.com)",
28 | "license": "MIT",
29 | "bugs": {
30 | "url": "https://github.com/shinzui/react-semantic-ui-kit/issues"
31 | },
32 | "homepage": "https://github.com/shinzui/react-semantic-ui-kit#readme",
33 | "peerDependencies": {
34 | "classnames": "^2.2.0",
35 | "react": "^15.1.0",
36 | "react-dom": "^15.1.0",
37 | "react-immutable-proptypes": "^1.5.0",
38 | "semantic-ui-css": "^2.1.8"
39 | },
40 | "devDependencies": {
41 | "babel-cli": "^6.2.0",
42 | "babel-eslint": "^6.0.4",
43 | "babel-loader": "^6.2.0",
44 | "babel-plugin-transform-runtime": "^6.1.18",
45 | "babel-preset-es2015": "^6.1.18",
46 | "babel-preset-react": "^6.1.18",
47 | "babel-preset-stage-0": "^6.1.18",
48 | "chai": "^3.4.1",
49 | "chai-enzyme": "^0.4.2",
50 | "classnames": "^2.2.0",
51 | "css-loader": "^0.23.0",
52 | "enzyme": "^2.3.0",
53 | "eslint": "^2.10.2",
54 | "eslint-loader": "^1.1.1",
55 | "eslint-plugin-react": "^5.1.1",
56 | "extract-text-webpack-plugin": "^1.0.1",
57 | "file-loader": "^0.8.4",
58 | "html-webpack-plugin": "^2.17.0",
59 | "immutable": "^3.7.5",
60 | "install": "^0.8.1",
61 | "mocha": "^2.3.4",
62 | "react": "^15.1.0",
63 | "react-addons-test-utils": "^15.1.0",
64 | "react-dom": "^15.1.0",
65 | "react-immutable-proptypes": "^1.5.0",
66 | "semantic-ui-css": "^2.1.8",
67 | "style-loader": "^0.13.0",
68 | "url-loader": "^0.5.6",
69 | "webpack": "^1.12.8",
70 | "webpack-dev-server": "^1.12.1"
71 | },
72 | "dependencies": {
73 | "react": "^15.1.0"
74 | }
75 | }
76 |
--------------------------------------------------------------------------------
/src/collections/Message.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../util/propsToClasses'
6 | import SemanticUiPropTypes from '../common/SemanticUiPropTypes'
7 |
8 | export default class Message extends Component {
9 |
10 | static propTypes = {
11 | children: PropTypes.node,
12 | size: PropTypes.oneOf(['small', 'large', 'huge', 'massive']),
13 | dismissible: PropTypes.bool,
14 | compact: PropTypes.bool,
15 | warning: PropTypes.bool,
16 | info: PropTypes.bool,
17 | positive: PropTypes.bool,
18 | success: PropTypes.bool,
19 | error: PropTypes.bool,
20 | success: PropTypes.bool,
21 | icon: PropTypes.bool,
22 | hidden: PropTypes.bool,
23 | visible: PropTypes.bool,
24 | floating: PropTypes.bool,
25 | color: SemanticUiPropTypes.color,
26 | attached: PropTypes.oneOf(['top', 'bottom'])
27 | }
28 |
29 | constructor(props) {
30 | super(props)
31 | this.dismiss = this.dismiss.bind(this)
32 | }
33 |
34 | state = {
35 | dismissed: false
36 | }
37 |
38 | attachedClasses() {
39 | const { attached } = this.props
40 |
41 | if(attached === 'top') {
42 | return 'attached'
43 | } else if(attached === 'bottom') {
44 | return 'bottom attached'
45 | }
46 | }
47 |
48 |
49 | dismiss() {
50 | this.setState({dismissed: true})
51 | }
52 |
53 | render() {
54 | const { size, className, color } = this.props
55 | const { dismissed } = this.state
56 |
57 | const classesFromProps = propsToClasses(['hidden', 'visible', 'floating',
58 | 'positive', 'success', 'negative', 'error',
59 | 'compact', 'info', 'warning', 'icon'], this.props)
60 |
61 | let classes = classNames('ui', this.attachedClasses(), classesFromProps,
62 | {'hidden': dismissed},
63 | size, color, 'message', className)
64 | let dismissIcon = this.props.dismissible ? : undefined
65 |
66 | return (
67 |
68 | {dismissIcon}
69 | {this.props.children}
70 |
)
71 | }
72 | }
73 |
--------------------------------------------------------------------------------
/src/collections/breadcrumb/Breadcrumb.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
4 | import classNames from 'classnames'
5 |
6 | export default class Breadcrumb extends Component {
7 |
8 | static propTypes = {
9 | size: SemanticUiPropTypes.size,
10 | children: PropTypes.node.isRequired
11 | }
12 |
13 | render() {
14 | const { size, children } = this.props
15 | const classes = classNames('ui', size, 'breadcrumb')
16 |
17 | return (
18 |
19 | {children}
20 |
21 | )
22 | }
23 |
24 | }
25 |
--------------------------------------------------------------------------------
/src/collections/breadcrumb/BreadcrumbDivider.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | const BreadcrumbDivider = (props) => {
4 | const { divider } = props
5 | return (
6 | {divider}
7 | )
8 | }
9 |
10 | BreadcrumbDivider.defaultProps = {
11 | divider: '/'
12 | }
13 |
14 | BreadcrumbDivider.propTypes = {
15 | divider: PropTypes.string.isRequired
16 | }
17 |
18 | export default BreadcrumbDivider
19 |
--------------------------------------------------------------------------------
/src/collections/breadcrumb/BreadcrumbSection.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | export default class BreadcrumbSection extends Component {
6 |
7 | static propTypes = {
8 | active: PropTypes.bool,
9 | href: PropTypes.string,
10 | text: PropTypes.string
11 | }
12 |
13 | render() {
14 | const { active, href, text, children } = this.props
15 | const classes = classNames({'active': active}, 'section')
16 |
17 | const sectionBody = text ? text : children
18 |
19 | if(active || !href) {
20 | return {sectionBody}
21 | } else {
22 | return {sectionBody}
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/collections/form/Form.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 |
7 | export default class Form extends Component {
8 |
9 | static propTypes = {
10 | valid: PropTypes.bool,
11 | reply: PropTypes.bool,
12 | loading: PropTypes.bool,
13 | equalWidth: PropTypes.bool,
14 | inverted: PropTypes.bool,
15 | size: PropTypes.oneOf(['small', 'large'])
16 | }
17 |
18 | render() {
19 | const { size, className } = this.props
20 | const classesFromProps = propsToClasses(['reply', 'equalWidth', 'loading', 'inverted'], this.props)
21 | const classes = classNames('ui', classesFromProps, size, 'form', {'error' : !this.props.valid}, className)
22 |
23 | return (
24 |
25 | {this.props.children}
26 |
27 | )
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/collections/form/FormField.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 | import ImmutablePropTypes from 'react-immutable-proptypes'
5 |
6 | import spellNumber from '../../util/spellNumber'
7 | import propsToClasses from '../../util/propsToClasses'
8 |
9 | import Label from '../../index'
10 |
11 | export default class FormField extends Component {
12 |
13 | static propTypes = {
14 | name: (props, propName, componentName) => {
15 | if(!props.hasOwnProperty('children')) {
16 | if(!props.hasOwnProperty(propName)) {
17 | return new Error(`Required ${propName} was not specified in ${componentName}`)
18 | }
19 | }
20 | },
21 | label: PropTypes.string,
22 | placeholder: PropTypes.string,
23 | width: PropTypes.number,
24 | errors: ImmutablePropTypes.list,
25 | onChange: PropTypes.func.isRequired,
26 | onBlur: PropTypes.func.isRequired,
27 | onFocus: PropTypes.func.isRequired,
28 | disabled: PropTypes.bool,
29 | inline: PropTypes.bool,
30 | required: PropTypes.bool,
31 | readOnly: PropTypes.bool
32 | }
33 |
34 | static defaultProps = {
35 | value: '',
36 | onChange: () => {},
37 | onBlur: () => {},
38 | onFocus: () => {}
39 | }
40 |
41 | constructor(props) {
42 | super(props)
43 | }
44 |
45 | widthClasses() {
46 | const { width } = this.props
47 |
48 | if(width) return `${spellNumber(width)} wide`
49 | }
50 |
51 | inputControl() {
52 | const { errors, label: labelText, name, value, placeholder, readOnly } = this.props
53 | const { onBlur, onFocus, onChange } = this.props
54 |
55 | const input =
56 |
61 |
62 | if(this.props.busy) {
63 | return (
64 | {input}
65 |
66 |
)
67 | } else {
68 | return (
69 |
70 | {input}
71 |
72 | )
73 | }
74 | }
75 |
76 | render() {
77 | const { errors, label: labelText, name, value, className, children } = this.props
78 | const hasErrors = errors && errors.size > 0
79 |
80 | let widthClasses = this.widthClasses()
81 | let label = labelText ? {labelText} : ''
82 | const classFromProps = propsToClasses(['disabled', 'inline', 'required'], this.props)
83 | let fieldClasses = classNames('ui', classFromProps, 'field', {'error': hasErrors}, widthClasses, className )
84 | let pointingLabel = hasErrors ? {errors.get(0)} : undefined
85 |
86 | const input = children ? {children}
: this.inputControl()
87 | return (
88 |
89 | {label}
90 | {input}
91 | {pointingLabel}
92 |
93 | )
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/collections/form/FormFieldGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import spellNumber from '../../util/spellNumber'
6 | import propsToClasses from '../../util/propsToClasses'
7 | import FormField from './FormField'
8 |
9 | export default class FormFieldGroup extends Component {
10 |
11 | static propTypes = {
12 | children: (props, propName, componentName) => {
13 | const prop = props[propName]
14 | if(Array.isArray(prop)) {
15 | if(prop.some( p => p.type !== FormField)) {
16 | return new Error(`${componentName} should only have FormField as children`)
17 | }
18 | } else {
19 | if(prop.type !== FormField) {
20 | return new Error(`${componentName} should only have FormField as children`)
21 | }
22 | }
23 | },
24 | fields: PropTypes.number,
25 | inline: PropTypes.bool,
26 | equalWidth: PropTypes.bool,
27 | grouped: PropTypes.bool
28 | }
29 |
30 | render() {
31 | const { className, children, fields } = this.props
32 | const classFromProps = propsToClasses(['inline', 'equalWidth', 'grouped'], this.props)
33 | const classes = classNames(spellNumber(fields), classFromProps, 'fields', className)
34 |
35 | return {children}
36 |
37 | }
38 |
39 | }
40 |
--------------------------------------------------------------------------------
/src/collections/grid/Column.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 | import { deviceWidthClasses, widthClasses,
5 | floatedClasses, alignedClasses } from '../../common/semanticClasses'
6 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
7 |
8 | export default class Column extends Component {
9 |
10 | static propTypes = {
11 | width: PropTypes.number,
12 | mobileWidth: PropTypes.number,
13 | tabletWidth: PropTypes.number,
14 | computerWidth: PropTypes.number,
15 | color: SemanticUiPropTypes.color,
16 | floated: SemanticUiPropTypes.floated,
17 | aligned: SemanticUiPropTypes.aligned,
18 | style: PropTypes.object
19 | }
20 |
21 | render() {
22 | const { className, style, color } = this.props
23 | const classes = classNames(widthClasses(this.props), deviceWidthClasses(this.props),
24 | alignedClasses(this.props), floatedClasses(this.props),
25 | color, 'column', className)
26 |
27 | return {this.props.children}
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/collections/grid/Grid.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import { columnClasses } from '../../common/semanticClasses'
6 | import propsToClasses from '../../util/propsToClasses'
7 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
8 | import { reversedDevicesClasses, alignedClasses } from '../../common/semanticClasses'
9 |
10 | export default class Grid extends Component {
11 |
12 | static propTypes = {
13 | children: PropTypes.node,
14 | columns: PropTypes.number,
15 | page: PropTypes.bool,
16 | container: PropTypes.bool,
17 | relaxed: PropTypes.bool,
18 | celled: PropTypes.bool,
19 | centered: PropTypes.bool,
20 | stackable: PropTypes.bool,
21 | padded: PropTypes.bool,
22 | internallyCelled: PropTypes.bool,
23 | equalWidth: PropTypes.bool,
24 | aligned: SemanticUiPropTypes.verticalAndHorizontalAlignment,
25 | reversedDevices: SemanticUiPropTypes.commonDevices,
26 | style: PropTypes.object
27 | }
28 |
29 | render() {
30 | const { page, container, internallyCelled, style, equalWidth, className } = this.props
31 | const classesFromProps = propsToClasses(['relaxed', 'celled', 'centered', 'stackable', 'padded'], this.props)
32 | const classes = classNames('ui', alignedClasses(this.props), columnClasses(this.props), classesFromProps,
33 | reversedDevicesClasses(this.props),
34 | {'internally celled': internallyCelled},
35 | {'equal width': equalWidth},
36 | 'grid', {'container': page || container}, className)
37 |
38 | return {this.props.children}
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/collections/grid/Row.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 | import spellNumber from '../../util/spellNumber'
5 | import propsToClasses from '../../util/propsToClasses'
6 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
7 | import { deviceClasses, alignedClasses } from '../../common/semanticClasses'
8 |
9 | export default class Row extends Component {
10 |
11 | static propTypes = {
12 | children: PropTypes.node,
13 | columns: PropTypes.number,
14 | doubling: PropTypes.bool,
15 | centered: PropTypes.bool,
16 | equalWidth: PropTypes.bool,
17 | aligned: SemanticUiPropTypes.aligned,
18 | devices: SemanticUiPropTypes.devices,
19 | style: PropTypes.object
20 | }
21 |
22 | columnClasses() {
23 | const { columns } = this.props
24 |
25 | if(columns) return `${spellNumber(columns)} column`
26 | }
27 |
28 | render() {
29 | const { style, className, equalWidth } = this.props
30 | const classesFromProps = propsToClasses(['centered', 'doubling'], this.props)
31 | let classes = classNames('ui', deviceClasses(this.props), alignedClasses(this.props),
32 | this.columnClasses(), {'equal width': equalWidth},
33 | classesFromProps, 'row', className)
34 |
35 | return {this.props.children}
36 | }
37 | }
38 |
39 |
--------------------------------------------------------------------------------
/src/collections/menu/Menu.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 | import propsToClasses from '../../util/propsToClasses'
5 | import { itemClasses } from '../../common/semanticClasses'
6 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
7 |
8 | import MenuItem from './MenuItem'
9 |
10 | export default class Menu extends Component {
11 |
12 | static propTypes = {
13 | children: (props, propName, componentName) => {
14 | const prop = props[propName]
15 |
16 | if(Array.isArray(prop)) {
17 | if(prop.some( p => (p.type !== MenuItem && p.type !== Menu))) {
18 | return new Error(`${componentName} should only have MenuItem or Menu as children`)
19 | }
20 | } else {
21 | if(prop.type !== MenuItem && prop.type !== Menu) {
22 | return new Error(`${componentName} should only have MenuItem or Menu as children`)
23 | }
24 | }
25 | },
26 | items: PropTypes.number,
27 | vertical: PropTypes.bool,
28 | basic: PropTypes.bool,
29 | borderless: PropTypes.bool,
30 | tabular: PropTypes.bool,
31 | text: PropTypes.bool,
32 | right: PropTypes.bool,
33 | parentMenu: PropTypes.bool,
34 | secondary: PropTypes.bool,
35 | pointing: PropTypes.bool,
36 | pagination: PropTypes.bool,
37 | compact: PropTypes.bool,
38 | stackable: PropTypes.bool,
39 | inverted: PropTypes.bool,
40 | icon: PropTypes.bool,
41 | labeledIcon: PropTypes.bool,
42 | fluid: PropTypes.bool,
43 | color: SemanticUiPropTypes.color,
44 | size: PropTypes.oneOf(['small', 'large'])
45 | }
46 |
47 | render() {
48 | const { className, parentMenu, color, labeledIcon, size } = this.props
49 | const classesFromProps = propsToClasses(['secondary', 'right', 'vertical',
50 | 'borderless', 'compact', 'pointing', 'pagination',
51 | 'icon', 'text', 'basic', 'fluid',
52 | 'tabular', 'stackable', 'inverted'], this.props)
53 | const classes = classNames({'ui': !parentMenu}, color, size, itemClasses(this.props),
54 | {'labeled icon': labeledIcon}, classesFromProps, 'menu', className)
55 |
56 | const children = React.Children.map(this.props.children, (child) => {
57 | if(child.type === MenuItem) {
58 | return child
59 | } else if(child.type === Menu) {
60 | return React.cloneElement(child, { parentMenu: true })
61 | }
62 | })
63 |
64 | return {children}
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/collections/menu/MenuItem.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 | import propsToClasses from '../../util/propsToClasses'
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 | import { fittedClasses } from '../../common/semanticClasses'
7 |
8 | export default class MenuItem extends Component {
9 |
10 | static propTypes = {
11 | active: PropTypes.bool,
12 | href: PropTypes.string,
13 | header: PropTypes.bool,
14 | disabled: PropTypes.bool,
15 | link: PropTypes.bool,
16 | down: PropTypes.bool,
17 | fitted: SemanticUiPropTypes.fitted,
18 | onClick: PropTypes.func,
19 | color: SemanticUiPropTypes.color
20 | }
21 |
22 | render() {
23 | const { className, href, children, onClick, color } = this.props
24 | const classesFromProps = propsToClasses(['active', 'disabled', 'link', 'down', 'header'], this.props)
25 | const classes = classNames(color, classesFromProps, fittedClasses(this.props), 'item', className)
26 |
27 | if(href) {
28 | return {children}
29 | } else {
30 | return {children}
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/collections/table/Table.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 | import propsToClasses from '../../util/propsToClasses'
7 | import { columnClasses } from '../../common/semanticClasses'
8 |
9 | export default class Table extends Component {
10 |
11 | static propTypes = {
12 | children: PropTypes.node.isRequired,
13 | celled: PropTypes.bool,
14 | definition: PropTypes.bool,
15 | structured: PropTypes.bool,
16 | singleLine: PropTypes.bool,
17 | fixed: PropTypes.bool,
18 | selectable: PropTypes.bool,
19 | striped: PropTypes.bool,
20 | basic: PropTypes.bool,
21 | color: SemanticUiPropTypes.color,
22 | inverted: PropTypes.bool,
23 | compact: PropTypes.bool,
24 | veryCompact: PropTypes.bool,
25 | padded: PropTypes.bool,
26 | veryPadded: PropTypes.bool,
27 | columns: PropTypes.number,
28 | stackable: PropTypes.bool,
29 | unstackable: PropTypes.bool,
30 | collapsing: PropTypes.bool,
31 | sortable: PropTypes.bool,
32 | size: PropTypes.oneOf(['small', 'large'])
33 | }
34 |
35 | render() {
36 | const { className, singleLine, color, veryCompact, veryPadded, size } = this.props
37 | const classesFromProps = propsToClasses(['selectable', 'structured', 'striped', 'basic',
38 | 'celled', 'definition', 'fixed', 'sortable',
39 | 'collapsing', 'inverted', 'compact', 'padded',
40 | 'stackable', 'unstackable'], this.props)
41 |
42 | const classes = classNames('ui', columnClasses(this.props), size, classesFromProps,
43 | {'single line': singleLine}, {'very compact': veryCompact}, {'very padded': veryPadded},
44 | color, 'table', className)
45 |
46 | return(
47 |
48 | {this.props.children}
49 |
50 | )
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/collections/table/TableCell.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
7 | import { alignedClasses, widthClasses, sortedClasses } from '../../common/semanticClasses'
8 |
9 | export default class TableCell extends Component {
10 |
11 | static propTypes = {
12 | positive: PropTypes.bool,
13 | negative: PropTypes.bool,
14 | error: PropTypes.bool,
15 | warning: PropTypes.bool,
16 | active: PropTypes.bool,
17 | disabled: PropTypes.bool,
18 | collapsing: PropTypes.bool,
19 | aligned: SemanticUiPropTypes.verticalAndHorizontalAlignment,
20 | header: PropTypes.bool,
21 | selectable: PropTypes.bool,
22 | width: PropTypes.number,
23 | sorted: PropTypes.oneOf(['ascending', 'descending'])
24 | }
25 |
26 | render() {
27 | const { className, header } = this.props
28 | const classesFromProps = propsToClasses(['selectable', 'positive', 'negative', 'error',
29 | 'warning', 'active', 'disabled', 'collapsing'], this.props)
30 |
31 | const classes = classNames(widthClasses(this.props), classesFromProps, alignedClasses(this.props),
32 | sortedClasses(this.props),className)
33 |
34 | if(header) {
35 | return {this.props.children}
36 | } else {
37 | return {this.props.children}
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/collections/table/TableFooter.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 |
7 | const TableFooter = (props) => {
8 | const { className, fullWidth, children } = props
9 | const classes = classNames({'full-width': fullWidth}, className)
10 |
11 | return {children}
12 | }
13 |
14 | TableFooter.propTypes = {
15 | fullWidth: PropTypes.bool
16 | }
17 |
18 | export default TableFooter
19 |
--------------------------------------------------------------------------------
/src/collections/table/TableHeader.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 |
7 | const TableHeader = (props) => {
8 | const { className, fullWidth, children } = props
9 | const classes = classNames({'full-width': fullWidth}, className)
10 |
11 | return {children}
12 | }
13 |
14 | TableHeader.propTypes = {
15 | fullWidth: PropTypes.bool
16 | }
17 |
18 | export default TableHeader
19 |
--------------------------------------------------------------------------------
/src/collections/table/TableRow.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
7 | import { alignedClasses } from '../../common/semanticClasses'
8 |
9 | export default class TableRow extends Component {
10 |
11 | static propTypes = {
12 | positive: PropTypes.bool,
13 | negative: PropTypes.bool,
14 | error: PropTypes.bool,
15 | warning: PropTypes.bool,
16 | active: PropTypes.bool,
17 | disabled: PropTypes.bool,
18 | aligned: SemanticUiPropTypes.verticalAndHorizontalAlignment,
19 | }
20 |
21 | render() {
22 | const { className } = this.props
23 | const classesFromProps = propsToClasses(['positive', 'negative',
24 | 'error', 'warning', 'active', 'disabled'], this.props)
25 |
26 | const classes = classNames(classesFromProps, alignedClasses(this.props), className)
27 |
28 | return {this.props.children}
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/common/SemanticUiPropTypes.js:
--------------------------------------------------------------------------------
1 | import { PropTypes } from 'react'
2 |
3 | const size = PropTypes.oneOf(['mini', 'tiny', 'small', 'medium', 'large', 'big', 'huge', 'massive'])
4 | const attached = PropTypes.oneOf(['top', 'bottom', 'both'])
5 | const labelAttachment = PropTypes.oneOf(['top', 'bottom', 'right', 'left', 'topLeft', 'bottomLeft', 'topRight', 'bottomRight'])
6 | const aligned = PropTypes.oneOf(['right', 'left', 'center'])
7 | const verticalAndHorizontalAlignment = PropTypes.oneOf(['right', 'left', 'center', 'top', 'bottom', 'center'])
8 | const verticalAlignment = PropTypes.oneOf(['top', 'bottom', 'middle'])
9 | const floated = PropTypes.oneOf(['right', 'left'])
10 | const color = PropTypes.oneOf(['red', 'orange', 'yellow', 'olive', 'green', 'teal', 'blue',
11 | 'violet', 'purple', 'pink', 'brown', 'grey', 'black'])
12 | const social = PropTypes.oneOf(['facebook', 'twitter', 'googlePlus' , 'vk', 'linkedIn', 'instagram', 'youtube'])
13 | const fitted = PropTypes.oneOf(['both', 'horizontally', 'vertically'])
14 |
15 | const devices = PropTypes.arrayOf(PropTypes.oneOf(['computer', 'tablet', 'mobile', 'largeScreen']))
16 | const commonDevices = PropTypes.arrayOf(PropTypes.oneOf(['computer', 'tablet', 'mobile']))
17 |
18 | const SemanticUiPropTypes = {
19 | attached,
20 | aligned,
21 | color,
22 | commonDevices,
23 | devices,
24 | fitted,
25 | floated,
26 | social,
27 | verticalAlignment,
28 | verticalAndHorizontalAlignment,
29 | labelAttachment,
30 | size
31 | }
32 |
33 | export default SemanticUiPropTypes
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/common/semanticClasses.js:
--------------------------------------------------------------------------------
1 | import spellNumber from '../util/spellNumber'
2 | import { splitAndLowerCamelCase } from '../util/string'
3 |
4 | export const attachedClasses = (props) => {
5 | const { attached } = props
6 |
7 | if(attached === 'top') {
8 | return 'top attached'
9 | } else if(attached === 'bottom') {
10 | return 'bottom attached'
11 | } else if(attached === 'both') {
12 | return 'attached'
13 | } else if(attached === 'topRight') {
14 | return 'top right attached'
15 | } else if(attached === 'topLeft') {
16 | return 'top left attached'
17 | } else if(attached === 'bottomRight') {
18 | return 'bottom right attached'
19 | } else if(attached === 'bottomLeft') {
20 | return 'bottom left attached'
21 | } else if(attached === 'left') {
22 | return 'left attached'
23 | } else if(attached === 'right') {
24 | return 'right attached'
25 | }
26 | }
27 |
28 | export const alignedClasses = (props) => {
29 | const { aligned } = props
30 |
31 | if(aligned === 'right') {
32 | return 'right aligned'
33 | } else if(aligned === 'left') {
34 | return 'left aligned'
35 | } else if(aligned === 'center') {
36 | return 'center aligned'
37 | } else if(aligned === 'middle') {
38 | return 'middle aligned'
39 | } else if(aligned === 'top') {
40 | return 'top aligned'
41 | } else if(aligned === 'bottom') {
42 | return 'bottom aligned'
43 | }
44 | }
45 |
46 | export const floatedClasses = (props) => {
47 | const { floated } = props
48 |
49 | if(floated === 'right') {
50 | return 'right floated'
51 | } else if(floated === 'left') {
52 | return 'left floated'
53 | }
54 | }
55 |
56 | export const columnClasses = (props) => {
57 | const { columns } = props
58 |
59 | if(columns) return `${spellNumber(columns)} column`
60 | }
61 |
62 | export const fittedClasses = (props) => {
63 | const { fitted } = props
64 |
65 | if(fitted === 'both') {
66 | return 'fitted'
67 | } else if(fitted === 'horizontally') {
68 | return 'horizontally fitted'
69 | } else if(fitted === 'vertically') {
70 | return 'vertically fitted'
71 | }
72 | }
73 |
74 | export const itemClasses = (props) => {
75 | const { items } = props
76 |
77 | if(items) return `${spellNumber(items)} item`
78 | }
79 |
80 | export const widthClasses = (props) => {
81 | const { width } = props
82 |
83 | if(width) return `${spellNumber(width)} wide`
84 | }
85 |
86 | export const reversedDevicesClasses = (props) => {
87 | const classes = []
88 | const { reversedDevices } = props
89 |
90 | if(reversedDevices) {
91 | reversedDevices.forEach( (device) => {
92 | classes.push(`${device} reversed`)
93 | })
94 |
95 | return classes.join(' ')
96 | }
97 | }
98 |
99 | export const deviceWidthClasses = (props) => {
100 | const classes = []
101 | const devices = ['mobile', 'tablet', 'computer']
102 |
103 | devices.forEach( (device) => {
104 | let width = props[`${device}Width`]
105 |
106 | if(width) {
107 | classes.push(`${spellNumber(width)} wide ${device}`)
108 | }
109 | })
110 |
111 | if(classes.length > 0) {
112 | return classes.join(' ')
113 | }
114 | }
115 |
116 | export const buttonClasses = (props) => {
117 | const { buttons } = props
118 |
119 | if(buttons) return spellNumber(buttons)
120 | }
121 |
122 | export const sortedClasses = (props) => {
123 | const { sorted } = props
124 |
125 | if(sorted === 'ascending') {
126 | return 'sorted ascending'
127 | } else if(sorted === 'descending') {
128 | return 'sorted descending'
129 | }
130 | }
131 |
132 | export const socialClasses = (props) => {
133 | const { social } = props
134 |
135 | if(social === 'googlePlus') {
136 | return 'google plus'
137 | } else if(social === 'linkedIn') {
138 | return 'linkedin'
139 | } else if(social) {
140 | return social
141 | }
142 | }
143 |
144 | export const deviceClasses = (props) => {
145 | const { devices } = props
146 |
147 | if(devices) {
148 | const classes = []
149 |
150 | devices.forEach( (device) => {
151 | classes.push(splitAndLowerCamelCase(device))
152 | })
153 |
154 | return `${classes.join(' ')} only`
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/elements/Container.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import SemanticUiPropTypes from '../common/SemanticUiPropTypes'
5 | import { alignedClasses }from '../common/semanticClasses'
6 |
7 | export default class Container extends Component {
8 |
9 | static propTypes = {
10 | text: PropTypes.bool,
11 | fluid: PropTypes.bool,
12 | justified: PropTypes.bool,
13 | aligned: SemanticUiPropTypes.aligned
14 | }
15 |
16 | render() {
17 | const { text, fluid, justified, className } = this.props
18 | const classes = classNames('ui', {'fluid': fluid}, {'text': text},
19 | alignedClasses(this.props), {'justified': justified},
20 | 'container', className)
21 |
22 | return {this.props.children}
23 | }
24 |
25 | }
26 |
--------------------------------------------------------------------------------
/src/elements/Divider.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../util/propsToClasses'
5 |
6 | export default class Divider extends Component {
7 |
8 | static propTypes = {
9 | element: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5']),
10 | horizontal: PropTypes.bool,
11 | inverted: PropTypes.bool,
12 | vertical: PropTypes.bool,
13 | header: PropTypes.bool,
14 | fitted: PropTypes.bool,
15 | hidden: PropTypes.bool,
16 | section: PropTypes.bool,
17 | clearing: PropTypes.bool
18 | }
19 |
20 | render() {
21 | const { header, element } = this.props
22 | const classesFromProps = propsToClasses(['vertical', 'horizontal', 'inverted', 'fitted', 'hidden', 'section', 'clearing'], this.props)
23 | const classes = classNames('ui', classesFromProps, 'divider', {'header': header})
24 |
25 | if(element) {
26 | return {this.props.children}
27 | } else {
28 | return {this.props.children}
29 | }
30 | }
31 |
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/src/elements/Flag.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | export default class Flag extends Component {
5 |
6 | static propTypes = {
7 | countryName: PropTypes.string,
8 | countryCode: PropTypes.string
9 | }
10 |
11 | render() {
12 | const { className, countryName, countryCode } = this.props
13 | const classes = classNames(countryName, countryCode, 'flag')
14 |
15 |
16 | return
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/elements/Header.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propToClasses from '../util/propsToClasses'
5 | import SemanticUiPropTypes from '../common/SemanticUiPropTypes'
6 | import { attachedClasses, alignedClasses, floatedClasses } from '../common/semanticClasses'
7 |
8 | export default class Header extends Component {
9 |
10 | static propTypes = {
11 | element: PropTypes.oneOf(['h1', 'h2', 'h3', 'h4', 'h5']),
12 | header: PropTypes.string,
13 | subheader: PropTypes.string,
14 | icon: PropTypes.bool,
15 | disabled: PropTypes.bool,
16 | dividing: PropTypes.bool,
17 | block: PropTypes.bool,
18 | inverted: PropTypes.bool,
19 | justified: PropTypes.bool,
20 | attached: SemanticUiPropTypes.attached,
21 | aligned: SemanticUiPropTypes.aligned,
22 | floated: SemanticUiPropTypes.floated
23 | }
24 |
25 | render() {
26 | const { className, element, header, subheader } = this.props
27 | const subheaderOnly = subheader && (header === undefined)
28 | const classesFromProps = propToClasses(['icon', 'disabled', 'dividing', 'justified', 'block', 'inverted'], this.props)
29 | const classes = classNames('ui', classesFromProps, {'sub': subheaderOnly},
30 | attachedClasses(this.props), alignedClasses(this.props), floatedClasses(this.props),
31 | 'header', className)
32 |
33 | let subheaderEl
34 | let headerText = header
35 |
36 | if(header && subheader) {
37 | subheaderEl = {subheader}
38 | } else if(subheader) {
39 | headerText = subheader
40 | }
41 |
42 | if(element) {
43 | return {headerText}{this.props.children}{subheaderEl}
44 | } else {
45 | return {headerText}{this.props.children}
46 | }
47 |
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/elements/Icon.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import { lowercase, splitAndLowerCamelCase } from '../util/string'
5 |
6 | const Icon = (props) => {
7 |
8 | const { className, type, outline, slash, square, circle, divider } = props
9 | const classes = classNames(splitAndLowerCamelCase(type), {'square': square}, {'circle': circle},
10 | {'slash': slash}, {'outline': outline}, 'icon', className, {'divider': divider})
11 |
12 | return
13 | }
14 |
15 | Icon.propTypes = {
16 | type: PropTypes.string.isRequired,
17 | outline: PropTypes.bool,
18 | square: PropTypes.bool,
19 | slash: PropTypes.bool,
20 | divider: PropTypes.bool
21 | }
22 |
23 | export default Icon
24 |
--------------------------------------------------------------------------------
/src/elements/Input.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../util/propsToClasses'
6 | import SemanticUiPropTypes from '../common/SemanticUiPropTypes'
7 |
8 | import { Label } from '../index'
9 |
10 | export default class Input extends Component {
11 |
12 | static propTypes = {
13 | loading: PropTypes.bool,
14 | disabled: PropTypes.bool,
15 | error: PropTypes.bool,
16 | focus: PropTypes.bool,
17 | transparent: PropTypes.bool,
18 | inverted: PropTypes.bool,
19 | fluid: PropTypes.bool,
20 | icon: PropTypes.bool,
21 | iconPosition: PropTypes.oneOf(['left', 'right']),
22 | label: PropTypes.oneOfType([
23 | PropTypes.string,
24 | PropTypes.element,
25 | PropTypes.bool
26 | ]),
27 | labelPosition: PropTypes.oneOf(['left', 'right']),
28 | action: PropTypes.bool,
29 | actionPosition: PropTypes.oneOf(['left', 'right']),
30 | size: SemanticUiPropTypes.size
31 | }
32 |
33 | iconClasses() {
34 | const { icon, iconPosition } = this.props
35 |
36 | if(icon) {
37 | return `${iconPosition} icon`
38 | }
39 | }
40 |
41 | labelClasses() {
42 | const { label, labelPosition, labeled } = this.props
43 |
44 | if(label) {
45 | return `${labelPosition} labeled`
46 | }
47 | }
48 |
49 | actionClasses() {
50 | const { action, actionPosition } = this.props
51 |
52 | if(action) {
53 | return `${actionPosition} action`
54 | }
55 | }
56 |
57 | labelElement() {
58 | const { label } = this.props
59 |
60 | if(label) {
61 |
62 | if(typeof label === 'string') {
63 | return {label}
64 | } else if(typeof label === 'boolean') {
65 | return undefined
66 | }
67 | else {
68 | return label
69 | }
70 | }
71 | }
72 |
73 | render() {
74 | const { size, className, loading, error, focus, label,
75 | iconPosition, labelPosition, actionPosition } = this.props
76 |
77 | const classesFromProps = propsToClasses(['disabled', 'transparent', 'inverted', 'fluid'], this.props)
78 |
79 | const classes = classNames('ui',this.iconClasses(), this.labelClasses(), this.actionClasses(),
80 | classesFromProps, size, 'input',
81 | {'loading': loading}, {'error': error}, {'focus': focus})
82 |
83 | let rightLabel, leftLabel
84 | if(label) {
85 | if(labelPosition === 'right') {
86 | rightLabel = this.labelElement()
87 | } else {
88 | leftLabel = this.labelElement()
89 | }
90 | }
91 |
92 | return (
93 |
94 | {leftLabel}
95 | {this.props.children}
96 | {rightLabel}
97 |
98 | )
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/elements/List.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../util/propsToClasses'
5 | import SemanticUiPropTypes from '../common/SemanticUiPropTypes'
6 | import { alignedClasses } from '../common/semanticClasses'
7 |
8 | /*eslint "react/no-multi-comp": 0 */
9 | class List extends Component {
10 |
11 | static propTypes = {
12 | relaxed: PropTypes.bool,
13 | veryRelaxed: PropTypes.bool,
14 | divided: PropTypes.bool,
15 | celled: PropTypes.bool,
16 | bulleted: PropTypes.bool,
17 | ordered: PropTypes.bool,
18 | simple: PropTypes.bool,
19 | link: PropTypes.bool,
20 | horizontal: PropTypes.bool,
21 | inverted: PropTypes.bool,
22 | selection: PropTypes.bool,
23 | animated: PropTypes.bool,
24 | aligned: SemanticUiPropTypes.verticalAlignment,
25 | size: SemanticUiPropTypes.size
26 | }
27 |
28 | element = 'div'
29 |
30 | render() {
31 | const { bulleted, ordered, simple, link, size, veryRelaxed } = this.props
32 | const classesFromProps = propsToClasses(['relaxed', 'animated', 'horizontal',
33 | 'divided', 'celled', 'selection',
34 | 'bulleted', 'ordered', 'link', 'inverted'], this.props)
35 |
36 | const classes = classNames('ui', size, {'very relaxed': veryRelaxed},
37 | alignedClasses(this.props), classesFromProps, 'list', this.props.className)
38 |
39 | if(bulleted && simple) this.element = 'ul'
40 | if(ordered && simple) this.element = 'ol'
41 |
42 | const children = React.Children.map(this.props.children, (child) => {
43 | return React.cloneElement(child, { bulleted: bulleted, ordered: ordered, simple: simple, link: link })
44 | })
45 |
46 | return (
47 |
48 | {children}
49 |
50 | )
51 | }
52 | }
53 |
54 | class ListItem extends Component {
55 |
56 | static propTypes = {
57 | bulleted: PropTypes.bool,
58 | ordered: PropTypes.bool,
59 | simple: PropTypes.bool,
60 | href: PropTypes.string,
61 | link: PropTypes.bool,
62 | active: PropTypes.bool
63 | }
64 |
65 | element = 'div'
66 |
67 | render() {
68 | const { bulleted, ordered, simple, href, link, active } = this.props
69 | const classes = classNames('item', {'active': active}, {'bulleted': bulleted && !simple}, { 'ordered': ordered && !simple}, this.props.className)
70 |
71 | if((bulleted || ordered) && simple) this.element = 'li'
72 |
73 | if(href) this.element = 'a'
74 | if(link && !active) this.element = 'a'
75 |
76 | return (
77 |
78 | {this.props.children}
79 |
80 | )
81 | }
82 |
83 | }
84 |
85 | export {
86 | List,
87 | ListItem
88 | }
89 |
--------------------------------------------------------------------------------
/src/elements/Rail.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | export default class Rail extends Component {
5 |
6 | static propTypes = {
7 | position: PropTypes.oneOf(['left', 'right']).isRequired,
8 | attached: PropTypes.bool,
9 | dividing: PropTypes.bool,
10 | internal: PropTypes.bool,
11 | close: PropTypes.bool
12 | }
13 |
14 | render() {
15 | const { position, close, internal, dividing, attached, className } = this.props
16 | const classes = classNames('ui', position, {'dividing': dividing}, {'internal': internal}, {'attached': attached}, {'close': close}, 'rail', className)
17 |
18 | return (
19 | {this.props.children}
20 | )
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/elements/button/Button.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
5 | import propsToClasses from '../../util/propsToClasses'
6 | import { floatedClasses, attachedClasses, socialClasses } from '../../common/semanticClasses'
7 |
8 | export default class Button extends Component {
9 |
10 | static propTypes = {
11 | basic: PropTypes.bool,
12 | compact: PropTypes.bool,
13 | primary: PropTypes.bool,
14 | secondary: PropTypes.bool,
15 | submit: PropTypes.bool,
16 | positive: PropTypes.bool,
17 | negative: PropTypes.bool,
18 | icon: PropTypes.bool,
19 | labeled: PropTypes.bool,
20 | labelPosition: PropTypes.oneOf(['left', 'right']),
21 | floated: SemanticUiPropTypes.floated,
22 | fluid: PropTypes.bool,
23 | circular: PropTypes.bool,
24 | fluid: PropTypes.bool,
25 | floated: SemanticUiPropTypes.floated,
26 | size: SemanticUiPropTypes.size,
27 | social: SemanticUiPropTypes.social,
28 | attached: PropTypes.oneOf(['left', 'right', 'top', 'bottom']),
29 | icon: PropTypes.bool,
30 | labeledIcon: PropTypes.bool,
31 | inverted: PropTypes.bool,
32 | active: PropTypes.bool,
33 | disabled: PropTypes.bool,
34 | loading: PropTypes.bool,
35 | color: SemanticUiPropTypes.color,
36 | animation: PropTypes.oneOf(['horizontal', 'vertical', 'fade']),
37 | onClick: PropTypes.func
38 | }
39 |
40 | static defaultProps = {
41 | onClick: (event) => {
42 | console.error('You did not implement onClick for your ')
43 | }
44 | }
45 |
46 | labelClasses() {
47 | const { labeled, labelPosition } = this.props
48 |
49 | if(labeled) {
50 | return `${labelPosition} labeled`
51 | }
52 | }
53 |
54 | animationClasses() {
55 | const { animation } = this.props
56 |
57 | if(animation === 'horizontal') {
58 | return 'animated'
59 | } else if (animation === 'vertical') {
60 | return 'vertical animated'
61 | } else if(animation === 'fade') {
62 | return 'animated fade'
63 | }
64 | }
65 |
66 | render() {
67 | const { labeledIcon, className, color, attached, labeled, size, onClick, ...other } = this.props
68 | const classesFromProps = propsToClasses(['circular', 'inverted', 'primary', 'secondary', 'basic',
69 | 'active', 'disabled', 'loading', 'submit',
70 | 'fluid', 'icon', 'compact'], this.props)
71 |
72 | const initialClassesFromProps = propsToClasses(['positive', 'negative', 'fluid'], this.props)
73 |
74 | const classes = classNames(initialClassesFromProps, 'ui', attachedClasses(this.props),
75 | this.labelClasses(this.props), classesFromProps,
76 | {'labeled icon': labeledIcon}, size,
77 | socialClasses(this.props), this.animationClasses(),
78 | floatedClasses(this.props), color,
79 | 'button', className)
80 |
81 | const Component = labeled || attached ? 'div' : 'button'
82 |
83 | return {this.props.children}
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/src/elements/button/ButtonGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../../util/propsToClasses'
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 | import { buttonClasses } from '../../common/semanticClasses'
7 |
8 | export default class ButtonGroup extends Component {
9 |
10 | static propTypes = {
11 | icon: PropTypes.bool,
12 | vertical: PropTypes.bool,
13 | color: SemanticUiPropTypes.color,
14 | labeledIcon: PropTypes.bool,
15 | basic: PropTypes.bool,
16 | buttons: PropTypes.number,
17 | size: SemanticUiPropTypes.size
18 | }
19 |
20 | render() {
21 | const { className, color, labeledIcon, size } = this.props
22 | const classesFromProps = propsToClasses(['icon', 'vertical', 'basic'], this.props)
23 | const classes = classNames(color, buttonClasses(this.props), 'ui', size, classesFromProps,
24 | {'labeled icon': labeledIcon}, 'buttons', className)
25 |
26 | return {this.props.children}
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/elements/extra/Actions.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const Actions = (props) => {
6 | const { className, children } = props
7 | const classes = classNames('actions', className)
8 |
9 | return {children}
10 | }
11 |
12 | export default Actions
13 |
--------------------------------------------------------------------------------
/src/elements/extra/Author.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classnames from 'classnames'
4 |
5 | const Author = (props) => {
6 | const { classname, children, href } = props
7 | const classes = classnames('author', classname)
8 |
9 | if(href) {
10 | return {children}
11 | } else {
12 | return {children}
13 | }
14 | }
15 |
16 | Author.propTypes = {
17 | href: PropTypes.string
18 | }
19 |
20 | export default Author
21 |
--------------------------------------------------------------------------------
/src/elements/extra/Avatar.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classnames from 'classnames'
4 |
5 | const Avatar = (props) => {
6 | const { classname, src, href } = props
7 | const classes = classnames('avatar', classname)
8 |
9 | if(href) {
10 | return
11 | } else {
12 | return
13 | }
14 | }
15 |
16 | Avatar.propTypes = {
17 | src: PropTypes.string.isRequired,
18 | href: PropTypes.string
19 | }
20 |
21 | export default Avatar
22 |
--------------------------------------------------------------------------------
/src/elements/extra/Content.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
7 | import { alignedClasses } from '../../common/semanticClasses'
8 |
9 | const Content = (props) => {
10 | const { className, children } = props
11 | const classesFromProps = propsToClasses(['extra', 'visible', 'hidden'], props)
12 | const classes = classNames(alignedClasses(props), classesFromProps, 'content', className)
13 |
14 | return {children}
15 | }
16 |
17 | Content.propTypes = {
18 | extra: PropTypes.bool,
19 | visible: PropTypes.bool,
20 | hidden: PropTypes.bool,
21 | aligned: SemanticUiPropTypes.verticalAlignment
22 | }
23 |
24 | export default Content
25 |
--------------------------------------------------------------------------------
/src/elements/extra/ContentDescription.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const ContentDescription = (props) => {
6 | const { className, children } = props
7 | const classes = classNames('description', className)
8 |
9 | return {children}
10 | }
11 |
12 | export default ContentDescription
13 |
--------------------------------------------------------------------------------
/src/elements/extra/ContentHeader.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const ContentHeader = (props) => {
6 | const { className, children, href } = props
7 | const classes = classNames('header', className)
8 |
9 | if(href) {
10 | return {children}
11 | } else {
12 | return {children}
13 | }
14 | }
15 |
16 | export default ContentHeader
17 |
--------------------------------------------------------------------------------
/src/elements/extra/ContentImages.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const ContentImages = (props) => {
6 | const { className, extra, children } = props
7 | const classes = classNames({'extra': extra}, 'images', className)
8 |
9 | return {children}
10 | }
11 |
12 | ContentImages.propTypes = {
13 | extra: PropTypes.bool
14 | }
15 |
16 | export default ContentImages
17 |
--------------------------------------------------------------------------------
/src/elements/extra/ContentSummary.jsx:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const ContentSummary = (props) => {
6 | const { className, children } = props
7 | const classes = classNames('summary', className)
8 |
9 | return {children}
10 | }
11 |
12 | export default ContentSummary
13 |
--------------------------------------------------------------------------------
/src/elements/extra/Date.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const Date = (props) => {
6 | const { className, children, inline } = props
7 | const classes = classNames('date', className)
8 |
9 | if(inline) {
10 | return {children}
11 | } else {
12 | return {children}
13 | }
14 | }
15 |
16 | Date.propTypes = {
17 | inline: PropTypes.bool
18 | }
19 |
20 | export default Date
21 |
22 |
--------------------------------------------------------------------------------
/src/elements/extra/Extra.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const Extra = (props) => {
6 | const { className, style, children } = props
7 | const classes = classNames('extra', className)
8 |
9 | return {children}
10 | }
11 |
12 | Extra.propTypes = {
13 | style: PropTypes.object
14 | }
15 |
16 | export default Extra
17 |
18 |
--------------------------------------------------------------------------------
/src/elements/extra/Meta.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 | import { floatedClasses } from '../../common/semanticClasses'
7 |
8 | const Meta = (props) => {
9 | const { className, children, floated } = props
10 | const classes = classNames(floatedClasses(props), 'metadata', className)
11 |
12 | return {children}
13 | }
14 |
15 | Meta.PropTypes = {
16 | floated: SemanticUiPropTypes.floated
17 | }
18 |
19 | export default Meta
20 |
--------------------------------------------------------------------------------
/src/elements/extra/MetaData.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 | import { floatedClasses } from '../../common/semanticClasses'
7 |
8 | const MetaData = (props) => {
9 | const { className, children, floated } = props
10 | const classes = classNames(floatedClasses(props), 'metadata', className)
11 |
12 | return {children}
13 | }
14 |
15 | MetaData.PropTypes = {
16 | floated: SemanticUiPropTypes.floated
17 | }
18 |
19 | export default MetaData
20 |
--------------------------------------------------------------------------------
/src/elements/extra/Text.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | const Text = (props) => {
6 | const { className, extra, children } = props
7 | const classes = classNames({'extra': extra}, 'text', className)
8 |
9 | return {children}
10 | }
11 |
12 | Text.propTypes = {
13 | extra: PropTypes.bool
14 | }
15 |
16 | export default Text
17 |
--------------------------------------------------------------------------------
/src/elements/image/Image.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
5 | import { alignedClasses, floatedClasses } from '../../common/semanticClasses'
6 | import propsToClasses from '../../util/propsToClasses'
7 |
8 | export default class Image extends Component {
9 |
10 | static propTypes = {
11 | children: PropTypes.node,
12 | src: PropTypes.string,
13 | href: PropTypes.string,
14 | size: SemanticUiPropTypes.size,
15 | wrapper: PropTypes.bool,
16 | avatar: PropTypes.bool,
17 | bordered: PropTypes.bool,
18 | fluid: PropTypes.bool,
19 | rounded: PropTypes.bool,
20 | circular: PropTypes.bool,
21 | centered: PropTypes.bool,
22 | hidden: PropTypes.bool,
23 | disabled: PropTypes.bool,
24 | aligned: SemanticUiPropTypes.verticalAlignment,
25 | floated: SemanticUiPropTypes.floated,
26 | dependent: PropTypes.bool
27 | }
28 |
29 | static defaultProps = {
30 | wrapper: false
31 | }
32 |
33 | render() {
34 | const { wrapper, size, src, href, hidden, disabled, className, style, children, dependent } = this.props
35 | const classesFromProps = propsToClasses(['avatar', 'bordered', 'fluid', 'rounded', 'circular', 'centered' ], this.props)
36 | const classes = classNames({'hidden': hidden}, {'disabled': disabled}, {'ui': !dependent},
37 | alignedClasses(this.props), size, floatedClasses(this.props),
38 | classesFromProps, 'image', className)
39 |
40 | if(wrapper && src) {
41 | return {children}
42 | } else if(wrapper) {
43 | return {children}
44 | } else if(href) {
45 | return {children}
46 | } else {
47 | return
48 | }
49 | }
50 |
51 | }
52 |
--------------------------------------------------------------------------------
/src/elements/image/ImageGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
5 |
6 | export default class ImageGroup extends Component {
7 |
8 | static propTypes = {
9 | size: SemanticUiPropTypes.size
10 | }
11 |
12 | render() {
13 | const { size, className } = this.props
14 |
15 | const classes = classNames('ui', size, 'images', className)
16 |
17 | return {this.props.children}
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/elements/label/Label.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../../util/propsToClasses'
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 | import { attachedClasses } from '../../common/semanticClasses'
7 |
8 | export default class Label extends Component {
9 |
10 | static propTypes = {
11 | basic: PropTypes.bool,
12 | tag: PropTypes.bool,
13 | circular: PropTypes.bool,
14 | horizontal: PropTypes.bool,
15 | image: PropTypes.bool,
16 | pointing: PropTypes.bool,
17 | floating: PropTypes.bool,
18 | size: SemanticUiPropTypes.size,
19 | pointingDirection: PropTypes.oneOf(['below', 'left', 'right']),
20 | attached: SemanticUiPropTypes.labelAttachment,
21 | color: SemanticUiPropTypes.color,
22 | leftCorner: PropTypes.bool,
23 | rightCornor: PropTypes.bool,
24 | leftRibbon: PropTypes.bool,
25 | rightRibbon: PropTypes.bool,
26 | href: PropTypes.string,
27 | generic: PropTypes.bool
28 | }
29 |
30 | pointingClasses() {
31 | const { pointing, pointingDirection } = this.props
32 |
33 | if(pointingDirection) {
34 | if(pointingDirection === 'below') {
35 | return 'pointing below'
36 | } else {
37 | return `${pointingDirection} pointing`
38 | }
39 | }
40 |
41 | if(pointing) {
42 | return 'pointing'
43 | }
44 |
45 | }
46 |
47 | cornerClasses() {
48 | const { leftCorner, rightCorner } = this.props
49 |
50 | if(leftCorner) {
51 | return 'left corner'
52 | } else if(rightCorner) {
53 | return 'right corner'
54 | }
55 | }
56 |
57 | ribbonClasses() {
58 | const { leftRibbon, rightRibbon} = this.props
59 |
60 | if(leftRibbon) {
61 | return 'left ribbon'
62 | } else if(rightRibbon) {
63 | return 'right ribbon'
64 | }
65 | }
66 |
67 | render() {
68 | const { className, pointingDirection, color, size, floating, href, generic } = this.props
69 |
70 | const classesFromProps = propsToClasses(['basic', 'tag', 'circular', 'image', 'horizontal'], this.props)
71 |
72 | const classes = classNames({'floating': floating}, {'ui': !generic}, this.pointingClasses(),
73 | color, attachedClasses(this.props),
74 | this.ribbonClasses(), this.cornerClasses(),
75 | classesFromProps, size, 'label', className )
76 |
77 | if(href) {
78 | return {this.props.children}
79 | } else {
80 | return {this.props.children}
81 | }
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/src/elements/label/LabelGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../../util/propsToClasses'
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 |
7 | export default class LabelGroup extends Component {
8 |
9 | static propTypes = {
10 | tag: PropTypes.bool,
11 | circular: PropTypes.bool,
12 | size: SemanticUiPropTypes.size,
13 | color: SemanticUiPropTypes.color
14 | }
15 |
16 | render() {
17 | const { className, color, size } = this.props
18 |
19 | const classesFromProps = propsToClasses(['tag', 'circular'], this.props)
20 |
21 | const classes = classNames('ui', color, classesFromProps, size, 'labels', className)
22 |
23 | return {this.props.children}
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/elements/segment/Segment.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
7 | import { attachedClasses, alignedClasses, floatedClasses } from '../../common/semanticClasses'
8 |
9 | export default class Segment extends Component {
10 |
11 | static propTypes = {
12 | raised: PropTypes.bool,
13 | stacked: PropTypes.bool,
14 | piled: PropTypes.bool,
15 | vertical: PropTypes.bool,
16 | disabled: PropTypes.bool,
17 | loading: PropTypes.bool,
18 | inverted: PropTypes.bool,
19 | padded: PropTypes.bool,
20 | veryPadded: PropTypes.bool,
21 | compact: PropTypes.bool,
22 | secondary: PropTypes.bool,
23 | tertiary: PropTypes.bool,
24 | circular: PropTypes.bool,
25 | clearing: PropTypes.bool,
26 | container: PropTypes.bool,
27 | basic: PropTypes.bool,
28 | color: SemanticUiPropTypes.color,
29 | attached: SemanticUiPropTypes.attached,
30 | aligned: SemanticUiPropTypes.aligned,
31 | floated: SemanticUiPropTypes.floated
32 | }
33 |
34 | render() {
35 | const props = ['basic', 'raised', 'stacked', 'piled', 'vertical', 'disabled', 'loading',
36 | 'secondary', 'tertiary', 'inverted', 'padded', 'compact', 'circular', 'clearing', 'container']
37 |
38 | const classesFromProps = propsToClasses(props, this.props)
39 | const classes = classNames('ui', classesFromProps, this.props.color,
40 | attachedClasses(this.props), alignedClasses(this.props), floatedClasses(this.props),
41 | {'very padded': this.props.veryPadded},
42 | 'segment', this.props.className)
43 |
44 | return {this.props.children}
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/elements/segment/SegmentGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 |
7 | export default class SegmentGroup extends Component {
8 |
9 | static propTypes = {
10 | horizontal: PropTypes.bool,
11 | raised: PropTypes.bool,
12 | stacked: PropTypes.bool,
13 | piled: PropTypes.bool,
14 | compact: PropTypes.bool
15 | }
16 |
17 | render() {
18 |
19 | const classesFromProps = propsToClasses(['horizontal', 'raised', 'stacked', 'piled', 'compact'], this.props)
20 | const classes = classNames('ui', classesFromProps, 'segments', this.props.className)
21 |
22 | return {this.props.children}
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/elements/step/Step.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../../util/propsToClasses'
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 |
7 | export default class Step extends Component {
8 |
9 | static propTypes = {
10 | completed: PropTypes.bool,
11 | active: PropTypes.bool,
12 | disabled: PropTypes.bool
13 | }
14 |
15 | render() {
16 | const { className } = this.props
17 | const classesFromProps = propsToClasses(['completed', 'active', 'disabled'], this.props)
18 | const classes = classNames(classesFromProps, 'step', className)
19 |
20 | return {this.props.children}
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/elements/step/StepGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../../util/propsToClasses'
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 | import { attachedClasses } from '../../common/semanticClasses'
7 | import spellNumber from '../../util/spellNumber'
8 |
9 | import Step from './Step'
10 |
11 | export default class StepGroup extends Component {
12 |
13 | static propTypes = {
14 | ordered: PropTypes.bool,
15 | vertical: PropTypes.bool,
16 | fluid: PropTypes.bool,
17 | size: PropTypes.oneOf(['small', 'large']),
18 | steps: PropTypes.number,
19 | attached: SemanticUiPropTypes.attached,
20 | stackable: PropTypes.bool,
21 | children: (props, propName, componentName) => {
22 | const prop = props[propName]
23 |
24 | if(Array.isArray(prop)) {
25 | if(prop.some( p => p.type !== Step)) {
26 | return new Error(`${componentName} should only have Step as children`)
27 | }
28 | } else {
29 | if(prop.type !== Step) {
30 | return new Error(`${componentName} should only have Step as children`)
31 | }
32 | }
33 | }
34 | }
35 |
36 | stepsClasses() {
37 | const { steps} = this.props
38 |
39 | if(steps) return spellNumber(steps)
40 | }
41 |
42 | render() {
43 | const { className, size, stackable } = this.props
44 | const classesFromProps = propsToClasses(['fluid', 'ordered', 'vertical'], this.props)
45 | const classes = classNames('ui', classesFromProps, this.stepsClasses(), attachedClasses(this.props),
46 | {'tablet stackable': stackable },
47 | size, 'steps', className)
48 |
49 | return {this.props.children}
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Breadcrumb from './collections/breadcrumb/Breadcrumb'
2 | import BreadcrumbDivider from './collections/breadcrumb/BreadcrumbDivider'
3 | import BreadcrumbSection from './collections/breadcrumb/BreadcrumbSection'
4 | import Form from './collections/form/Form'
5 | import FormField from './collections/form/FormField'
6 | import FormFieldGroup from './collections/form/FormFieldGroup'
7 | import Grid from './collections/grid/Grid'
8 | import Column from './collections/grid/Column'
9 | import Row from './collections/grid/Row'
10 | import Message from './collections/Message'
11 | import Menu from './collections/menu/Menu'
12 | import MenuItem from './collections/menu/MenuItem'
13 | import Table from './collections/table/Table'
14 | import TableCell from './collections/table/TableCell'
15 | import TableRow from './collections/table/TableRow'
16 | import TableHeader from './collections/table/TableHeader'
17 | import TableFooter from './collections/table/TableFooter'
18 |
19 | import Modal from './modules/Modal'
20 | import ModalHeader from './modules/ModalHeader'
21 | import ModalContent from './modules/ModalContent'
22 | import ModalActions from './modules/ModalActions'
23 |
24 | import Button from './elements/button/Button'
25 | import ButtonGroup from './elements/button/ButtonGroup'
26 | import Container from './elements/Container'
27 | import Divider from './elements/Divider'
28 | import Flag from './elements/Flag'
29 | import Header from './elements/Header'
30 | import Icon from './elements/Icon'
31 | import Input from './elements/Input'
32 | import Label from './elements/label/Label'
33 | import LabelGroup from './elements/label/LabelGroup'
34 | import Segment from './elements/segment/Segment'
35 | import SegmentGroup from './elements/segment/SegmentGroup'
36 | import Image from './elements/image/Image'
37 | import ImageGroup from './elements/image/ImageGroup'
38 | import { List, ListItem} from './elements/List'
39 | import Rail from './elements/Rail'
40 | import Step from './elements/step/Step'
41 | import StepGroup from './elements/step/StepGroup'
42 |
43 | import Card from './views/card/Card'
44 | import CardGroup from './views/card/CardGroup'
45 | import Comment from './views/comment/Comment'
46 | import CommentGroup from './views/comment/CommentGroup'
47 | import Feed from './views/feed/Feed'
48 | import FeedEvent from './views/feed/FeedEvent'
49 | import Item from './views/item/Item'
50 | import ItemGroup from './views/item/ItemGroup'
51 | import Statistic from './views/statistic/Statistic'
52 | import StatisticGroup from './views/statistic/StatisticGroup'
53 |
54 | import Actions from './elements/extra/Actions'
55 | import Author from './elements/extra/Author'
56 | import Avatar from './elements/extra/Avatar'
57 | import Content from './elements/extra/Content'
58 | import ContentHeader from './elements/extra/ContentHeader'
59 | import ContentDescription from './elements/extra/ContentDescription'
60 | import ContentImages from './elements/extra/ContentImages'
61 | import ContentSummary from './elements/extra/ContentSummary'
62 | import Date from './elements/extra/Date'
63 | import Extra from './elements/extra/Extra'
64 | import Meta from './elements/extra/Meta'
65 | import MetaData from './elements/extra/MetaData'
66 | import Text from './elements/extra/Text'
67 |
68 | import Checkbox from './modules/Checkbox'
69 |
70 | export {
71 | Actions,
72 | Author,
73 | Avatar,
74 | Breadcrumb,
75 | BreadcrumbDivider,
76 | BreadcrumbSection,
77 | Button,
78 | ButtonGroup,
79 | Card,
80 | CardGroup,
81 | Checkbox,
82 | Column,
83 | Comment,
84 | CommentGroup,
85 | Container,
86 | Content,
87 | ContentHeader,
88 | ContentDescription,
89 | ContentImages,
90 | ContentSummary,
91 | Date,
92 | Divider,
93 | Extra,
94 | Feed,
95 | FeedEvent,
96 | Header,
97 | Icon,
98 | Input,
99 | Flag,
100 | Form,
101 | FormField,
102 | FormFieldGroup,
103 | Grid,
104 | Image,
105 | ImageGroup,
106 | Item,
107 | ItemGroup,
108 | Label,
109 | LabelGroup,
110 | List,
111 | ListItem,
112 | Menu,
113 | MenuItem,
114 | Meta,
115 | MetaData,
116 | Modal,
117 | ModalHeader,
118 | ModalContent,
119 | ModalActions,
120 | Message,
121 | Rail,
122 | Row,
123 | Segment,
124 | SegmentGroup,
125 | Statistic,
126 | StatisticGroup,
127 | Step,
128 | StepGroup,
129 | Table,
130 | TableCell,
131 | TableRow,
132 | TableHeader,
133 | TableFooter,
134 | Text
135 | }
136 |
--------------------------------------------------------------------------------
/src/modules/Checkbox.jsx:
--------------------------------------------------------------------------------
1 | import React, { PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../util/propsToClasses'
6 |
7 | const Checkbox = (props) => {
8 | const { label, name, checked, className, children, onChange, radio } = props
9 | const classesFromProps = propsToClasses(['fitted', 'radio'], props)
10 | const classes = classNames('ui', classesFromProps, 'checkbox', className)
11 |
12 | const labelEl = label ? {label} : undefined
13 |
14 | const type = radio ? 'radio' : 'checkbox'
15 |
16 | return (
17 |
18 |
19 | {labelEl}
20 | {children}
21 |
22 | )
23 | }
24 |
25 | Checkbox.propTypes = {
26 | label: PropTypes.string,
27 | name: PropTypes.string.isRequired,
28 | checked: PropTypes.bool,
29 | onChange: PropTypes.func,
30 | fitted: PropTypes.bool,
31 | radio: PropTypes.bool
32 | }
33 |
34 | export default Checkbox
35 |
--------------------------------------------------------------------------------
/src/modules/Modal.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | export default class Modal extends Component {
5 |
6 | static propTypes = {
7 | isVisible: PropTypes.bool.isRequired,
8 | ref: PropTypes.string
9 | }
10 |
11 | static defaultProps = {
12 | ref: 'modal',
13 | isVisible: false
14 | }
15 |
16 | render() {
17 | let classes = classNames('ui', this.props.className, 'modal', {'transition visible active': this.props.isVisible})
18 |
19 | return (
20 |
21 | {this.props.children}
22 |
23 | )
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/modules/ModalActions.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | export default class ModalActions extends Component {
5 |
6 | static propTypes = {
7 | submitHandler: PropTypes.func.isRequired,
8 | cancelHandler: PropTypes.func.isRequired
9 | }
10 |
11 | static defaultProps = {
12 | cancelText: 'Cancel',
13 | submitText: 'Submit'
14 | }
15 |
16 | render() {
17 |
18 | return (
19 |
20 |
21 | {this.props.cancelText}
22 |
23 |
24 | {this.props.submitText}
25 |
26 |
27 |
28 |
29 | )
30 | }
31 |
32 | }
33 |
--------------------------------------------------------------------------------
/src/modules/ModalContent.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | export default class Modal extends Component {
5 |
6 | render() {
7 | return (
8 |
9 | {this.props.children}
10 |
11 | )
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/modules/ModalHeader.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | export default class ModelHeader extends Component {
5 |
6 | render() {
7 | const classes = classNames('header', this.props.className)
8 | return (
9 |
10 | {this.props.children}
11 |
12 | )
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/src/util/propsToClasses.js:
--------------------------------------------------------------------------------
1 | import { splitAndLowerCamelCase } from './string'
2 |
3 | const propToClasses = (propNames, props) => {
4 | let classes = []
5 |
6 | propNames.forEach( (prop) => {
7 | if(props[prop]) {
8 | classes.push(splitAndLowerCamelCase(prop))
9 | }
10 | })
11 |
12 | return classes
13 | }
14 |
15 | export default propToClasses
16 |
--------------------------------------------------------------------------------
/src/util/spellNumber.js:
--------------------------------------------------------------------------------
1 | const spellNumber = (number) => {
2 | const intNumber = parseInt(number, 10)
3 |
4 | const nums = ['one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine', 'ten', 'eleven', 'twelve', 'thirteen', 'fourteen', 'fifteen', 'sixteen']
5 |
6 | return nums[intNumber - 1]
7 | }
8 |
9 | export default spellNumber
10 |
--------------------------------------------------------------------------------
/src/util/string.js:
--------------------------------------------------------------------------------
1 | export const capitalize = (string) => {
2 | if(string) {
3 | return string.charAt(0).toUpperCase() + string.slice(1)
4 | }
5 | }
6 |
7 | export const lowercase = (string) => {
8 | if(string) {
9 | return string.charAt(0).toLowerCase() + string.slice(1)
10 | }
11 | }
12 |
13 | export const splitAndLowerCamelCase = (string) => {
14 | const upperToSpaceLower = (match) => {
15 | return ` ${match.toLowerCase()}`
16 | }
17 |
18 | if(string) {
19 | return string.replace(/[A-Z]/g, upperToSpaceLower).trim()
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/src/views/card/Card.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 | import propsToClasses from '../../util/propsToClasses'
5 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
6 |
7 | export default class Card extends Component {
8 |
9 | static propTypes = {
10 | children: PropTypes.node,
11 | fluid: PropTypes.bool,
12 | centered: PropTypes.bool,
13 | href: PropTypes.string,
14 | grouped: PropTypes.bool,
15 | color: SemanticUiPropTypes.color
16 | }
17 |
18 | render() {
19 | const { className, href, children, grouped, color } = this.props
20 | const classesFromProps = propsToClasses(['fluid', 'centered'], this.props)
21 | const classes = classNames({'ui': !grouped}, classesFromProps, color,
22 | 'card', className)
23 |
24 |
25 | if(href) {
26 | return {children}
27 | } else {
28 | return {children}
29 | }
30 | }
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/src/views/card/CardGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 | import spellNumber from '../../util/spellNumber'
7 | import Card from './Card'
8 |
9 | export default class CardGroup extends Component {
10 |
11 | static propTypes = {
12 | columns: PropTypes.number,
13 | stackable: PropTypes.bool,
14 | doubling: PropTypes.bool,
15 | children: (props, propName, componentName) => {
16 | const prop = props[propName]
17 |
18 | if(Array.isArray(prop)) {
19 | if(prop.some( p => p.type !== Card)) {
20 | return new Error(`${componentName} should only have Card as children`)
21 | }
22 | } else {
23 | if(prop.type !== Card) {
24 | return new Error(`${componentName} should only have Card as children`)
25 | }
26 | }
27 | }
28 | }
29 |
30 | render() {
31 | const { className, children, columns } = this.props
32 | const classFromProps = propsToClasses(['stackable', 'doubling'], this.props)
33 | const classes = classNames('ui', spellNumber(columns), classFromProps, 'cards', className)
34 |
35 | return (
36 |
37 | {React.Children.map(children, (child) => {
38 | return React.cloneElement(child, { grouped: true})
39 | })}
40 |
41 | )
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/views/comment/Comment.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | export default class CommentGroup extends Component {
6 |
7 | render() {
8 | const { className } = this.props
9 | const classes = classNames('comment', className)
10 |
11 | return {this.props.children}
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/src/views/comment/CommentGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import propsToClasses from '../../util/propsToClasses'
6 |
7 | export default class CommentGroup extends Component {
8 |
9 | static propTypes = {
10 | minimal: PropTypes.bool,
11 | collapsed: PropTypes.bool,
12 | threaded: PropTypes.bool
13 | }
14 |
15 | render() {
16 | const { className } = this.props
17 | const classesFromProps = propsToClasses(['minimal', 'collapsed', 'threaded'], this.props)
18 | const classes = classNames('ui', classesFromProps, 'comments', className)
19 |
20 | return {this.props.children}
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/views/feed/Feed.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | import FeedEvent from './FeedEvent'
6 |
7 | export default class Feed extends Component {
8 |
9 | static propTypes = {
10 | size: PropTypes.oneOf(['small', 'large']),
11 | children: (props, propName, componentName) => {
12 | const prop = props[propName]
13 |
14 | if(Array.isArray(prop)) {
15 | if(prop.some( p => (p.type !== FeedEvent))) {
16 | return new Error(`${componentName} should only have FeedEvent as children`)
17 | }
18 | } else {
19 | if(prop.type !== FeedEvent) {
20 | return new Error(`${componentName} should only have FeedEvent as children`)
21 | }
22 | }
23 | }
24 | }
25 |
26 | render() {
27 | const { className, size } = this.props
28 | const classes = classNames('ui', size, 'feed', className)
29 |
30 | return {this.props.children}
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/views/feed/FeedEvent.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | export default class FeedEvent extends Component {
6 |
7 | static propTypes = {
8 | children: PropTypes.node
9 | }
10 |
11 | render() {
12 | const { className } = this.props
13 | const classes = classNames('event', className)
14 |
15 | return {this.props.children}
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/views/item/Item.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 |
3 | import classNames from 'classnames'
4 |
5 | export default class Item extends Component {
6 |
7 | render() {
8 | const classes = classNames('item', this.props.className)
9 |
10 | return {this.props.children}
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/views/item/ItemGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import propsToClasses from '../../util/propsToClasses'
5 |
6 | export default class ItemGroup extends Component {
7 |
8 | static proptypes = {
9 | divided: PropTypes.bool,
10 | relaxed: PropTypes.bool,
11 | link: PropTypes.bool,
12 | }
13 |
14 | render() {
15 | const propsFromClasses = propsToClasses(['divided', 'relaxed', 'link'], this.props)
16 | const classes = classNames('ui', propsFromClasses, 'items', this.props.className)
17 |
18 | return {this.props.children}
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/views/statistic/Statistic.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
5 | import propsToClasses from '../../util/propsToClasses'
6 |
7 | export default class Statistic extends Component {
8 |
9 | static propTypes = {
10 | value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
11 | label: PropTypes.string.isRequired,
12 | size: SemanticUiPropTypes.size,
13 | color: SemanticUiPropTypes.color,
14 | labelPosition: PropTypes.oneOf(['top', 'bottom']),
15 | horizontal: PropTypes.bool,
16 | inverted: PropTypes.bool,
17 | textValue: PropTypes.bool,
18 | style: PropTypes.object
19 | }
20 |
21 | static defaultProps = {
22 | labelPosition: 'bottom'
23 | }
24 |
25 | render() {
26 | const { value, label, className, size, style, textValue,
27 | horizontal, labelPosition, color, inverted, children } = this.props
28 |
29 | const classesFromProps = propsToClasses(['inverted', 'horizontal'], this.props)
30 |
31 | const classes = classNames('ui', classesFromProps, size, color, 'statistic', className)
32 | const valueClasses = classNames({'text': textValue}, 'value')
33 |
34 | const valueEl = {value}
35 | const labelEl = {label}
36 |
37 | const top = labelPosition === 'top' ? labelEl : valueEl
38 | const bottom = labelPosition === 'bottom' ? labelEl : valueEl
39 |
40 | return (
41 |
42 | {top}
43 | {bottom}
44 |
45 | )
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/views/statistic/StatisticGroup.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component, PropTypes } from 'react'
2 | import classNames from 'classnames'
3 |
4 | import SemanticUiPropTypes from '../../common/SemanticUiPropTypes'
5 | import spellNumber from '../../util/spellNumber'
6 |
7 | import Statistic from './Statistic'
8 |
9 | export default class StatisticGroup extends Component {
10 |
11 | static propTypes = {
12 | style: PropTypes.object,
13 | horizontal: PropTypes.bool,
14 | stats: PropTypes.number,
15 | children: (props, propName, componentName) => {
16 | const prop = props[propName]
17 |
18 | if(Array.isArray(prop)) {
19 | if(prop.some( p => p.type !== Statistic)) {
20 | return new Error(`${componentName} should only have Statistic as children`)
21 | }
22 | } else {
23 | if(prop.type !== Statistic) {
24 | return new Error(`${componentName} should only have Statistic as children`)
25 | }
26 | }
27 | }
28 | }
29 |
30 | render() {
31 | const { className, children, style, horizontal, stats } = this.props
32 | const classes = classNames('ui', {'horizontal': horizontal}, spellNumber(stats), 'statistics', className)
33 |
34 | return {children}
35 | }
36 |
37 | }
38 |
--------------------------------------------------------------------------------
/test/common/semanticClasses_spec.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai'
2 |
3 | import { deviceWidthClasses, reversedDevicesClasses } from '../../src/common/semanticClasses'
4 |
5 | describe('deviceWidthClasses ', () => {
6 |
7 | it('should return the specific device width classes', () => {
8 | const expectedWidth = 'ten wide mobile five wide tablet two wide computer'
9 | expect(deviceWidthClasses({mobileWidth: 10, tabletWidth: 5, computerWidth: 2})).to.eq(expectedWidth)
10 | })
11 |
12 | it('should support only one device', () => {
13 | const expectedWidth = 'two wide computer'
14 | expect(deviceWidthClasses({computerWidth: 2})).to.eq(expectedWidth)
15 | })
16 |
17 | it('should not break with missing props', () => {
18 | expect(deviceWidthClasses({})).to.eq(undefined)
19 | })
20 | })
21 |
22 | describe('reversedDeviceWidthClasses', () => {
23 |
24 | it('should return the reversed devices classes', () => {
25 | const expectedClasses = 'mobile reversed tablet reversed'
26 | expect(reversedDevicesClasses({reversedDevices: ['mobile', 'tablet']})).to.eq(expectedClasses)
27 | })
28 |
29 | it('should not break with missing props', () => {
30 | expect(deviceWidthClasses({})).to.eq(undefined)
31 | })
32 |
33 | })
34 |
--------------------------------------------------------------------------------
/test/components/elements/Rail_spec.js:
--------------------------------------------------------------------------------
1 | import React from 'react'
2 | import { shallow } from 'enzyme'
3 | import { expect } from 'chai'
4 |
5 | import { Rail } from '../../../src/index'
6 |
7 | describe(' ', () => {
8 |
9 | it('should have ui rail classes', () => {
10 | const wrapper = shallow(Right rail
)
11 | expect(wrapper.find('div')).to.have.className('ui right rail')
12 | })
13 |
14 | })
15 |
--------------------------------------------------------------------------------
/test/test_helper.js:
--------------------------------------------------------------------------------
1 | import chai from 'chai'
2 | import chaiEnzyme from 'chai-enzyme'
3 |
4 | chai.use(chaiEnzyme())
5 |
--------------------------------------------------------------------------------
/test/util/string_spec.js:
--------------------------------------------------------------------------------
1 | import { expect } from 'chai'
2 |
3 | import { splitAndLowerCamelCase } from '../../src/util/string'
4 |
5 |
6 | describe('splitAndLowerCamelCase', () => {
7 |
8 | it('should split a camel case word and lower case it', () => {
9 | expect(splitAndLowerCamelCase('fullScreen')).to.eq('full screen')
10 | })
11 |
12 | it('should support more than two words', () => {
13 | expect(splitAndLowerCamelCase('fullScreenComputer')).to.eq('full screen computer')
14 | })
15 |
16 | it('should not break with empty strings', () => {
17 | expect(splitAndLowerCamelCase(' ')).to.eq('')
18 | })
19 |
20 | it('should not change non camelcased words', () => {
21 | expect(splitAndLowerCamelCase('mobile')).to.eq('mobile')
22 | })
23 |
24 | })
25 |
--------------------------------------------------------------------------------
/webpack.config.dev.js:
--------------------------------------------------------------------------------
1 | var path = require('path')
2 | var webpack = require('webpack')
3 | var HtmlWebpackPlugin = require('html-webpack-plugin')
4 |
5 | var ROOT_PATH = path.resolve(__dirname)
6 |
7 | module.exports = {
8 | devtool: '#source-map',
9 | resolve: {
10 | extensions: ['', '.js', '.jsx']
11 | },
12 | devServer: {
13 | contentBase: './demo/'
14 | },
15 | entry: [
16 | 'webpack-dev-server/client?http://0.0.0.0:8080',
17 | 'webpack/hot/only-dev-server',
18 | path.join(__dirname, 'demo/index.js')
19 | ],
20 | output: {
21 | path: path.join(__dirname, '/dist/'),
22 | filename: '[name].js',
23 | publicPath: '/'
24 | },
25 | plugins: [
26 | new webpack.optimize.OccurenceOrderPlugin(),
27 | new webpack.HotModuleReplacementPlugin(),
28 | new webpack.NoErrorsPlugin(),
29 | new HtmlWebpackPlugin({
30 | inject: 'body',
31 | filename: 'demo/index.html'
32 | }),
33 |
34 | new webpack.DefinePlugin({
35 | 'process.env.NODE_ENV': JSON.stringify('development'),
36 | '__DEV__': JSON.stringify(process.env.NODE_ENV)
37 | })
38 | ],
39 | module: {
40 | preLoaders: [{
41 | test: /\.jsx?$/,
42 | loader: 'eslint-loader',
43 | includes: [path.resolve(ROOT_PATH, 'src'), path.resolve(ROOT_PATH, 'demo')],
44 | exclude: /node_modules/
45 | }],
46 |
47 | loaders: [{
48 | test: /\.jsx?$/,
49 | exclude: /node_modules/,
50 | includes: [path.resolve(ROOT_PATH, 'src'), path.resolve(ROOT_PATH, 'demo')],
51 | loader: 'babel'
52 | }, {
53 | test: /\.json?$/,
54 | loader: 'json'
55 | }, {
56 | test: /\.css$/,
57 | loaders: ['style', 'css']
58 | }, {
59 | test: /\.(otf|eot|jpg|png|gif|svg|ttf|woff|woff2)(\?(\d+#?.*|v=[0-9]\.[0-9]\.[0-9]))?$/,
60 | loader: 'url?limit=8192'
61 | }]
62 | },
63 | eslint: {
64 | failOnError: false
65 | }
66 | }
67 |
--------------------------------------------------------------------------------