fron-ui 1.0.0rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (140) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +3 -0
  3. data/.rubocop.yml +38 -0
  4. data/.ruby-gemset +1 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +7 -0
  7. data/.yardopts +8 -0
  8. data/Gemfile +8 -0
  9. data/Gemfile.lock +105 -0
  10. data/Rakefile +37 -0
  11. data/Readme.md +4 -0
  12. data/db.json +192 -0
  13. data/fron-ui.gemspec +21 -0
  14. data/lib/fron-ui.rb +1 -0
  15. data/lib/fron_ui.rb +5 -0
  16. data/lib/fron_ui/version.rb +7 -0
  17. data/opal/fron-ui/base.rb +49 -0
  18. data/opal/fron-ui/behaviors/action.rb +40 -0
  19. data/opal/fron-ui/behaviors/actions.rb +40 -0
  20. data/opal/fron-ui/behaviors/confirmation.rb +23 -0
  21. data/opal/fron-ui/behaviors/dropdown.rb +27 -0
  22. data/opal/fron-ui/behaviors/file.rb +48 -0
  23. data/opal/fron-ui/behaviors/intendable_children.rb +76 -0
  24. data/opal/fron-ui/behaviors/keydown.rb +31 -0
  25. data/opal/fron-ui/behaviors/loop.rb +41 -0
  26. data/opal/fron-ui/behaviors/render.rb +30 -0
  27. data/opal/fron-ui/behaviors/rest.rb +121 -0
  28. data/opal/fron-ui/behaviors/selectable_children.rb +67 -0
  29. data/opal/fron-ui/behaviors/serialize.rb +32 -0
  30. data/opal/fron-ui/behaviors/shortcuts.rb +35 -0
  31. data/opal/fron-ui/behaviors/state.rb +56 -0
  32. data/opal/fron-ui/behaviors/transition.rb +63 -0
  33. data/opal/fron-ui/components/action.rb +18 -0
  34. data/opal/fron-ui/components/box.rb +17 -0
  35. data/opal/fron-ui/components/button.rb +61 -0
  36. data/opal/fron-ui/components/calendar.rb +129 -0
  37. data/opal/fron-ui/components/checkbox.rb +57 -0
  38. data/opal/fron-ui/components/chooser.rb +246 -0
  39. data/opal/fron-ui/components/color_panel.rb +235 -0
  40. data/opal/fron-ui/components/color_picker.rb +111 -0
  41. data/opal/fron-ui/components/container.rb +61 -0
  42. data/opal/fron-ui/components/date_picker.rb +141 -0
  43. data/opal/fron-ui/components/drag.rb +76 -0
  44. data/opal/fron-ui/components/dropdown.rb +72 -0
  45. data/opal/fron-ui/components/icon.rb +29 -0
  46. data/opal/fron-ui/components/image.rb +77 -0
  47. data/opal/fron-ui/components/input.rb +30 -0
  48. data/opal/fron-ui/components/label.rb +9 -0
  49. data/opal/fron-ui/components/list.rb +34 -0
  50. data/opal/fron-ui/components/loader.rb +63 -0
  51. data/opal/fron-ui/components/modal.rb +0 -0
  52. data/opal/fron-ui/components/notifications.rb +73 -0
  53. data/opal/fron-ui/components/number.rb +202 -0
  54. data/opal/fron-ui/components/progress.rb +52 -0
  55. data/opal/fron-ui/components/slider.rb +47 -0
  56. data/opal/fron-ui/components/tabs.rb +149 -0
  57. data/opal/fron-ui/components/textarea.rb +13 -0
  58. data/opal/fron-ui/components/time.rb +65 -0
  59. data/opal/fron-ui/components/title.rb +34 -0
  60. data/opal/fron-ui/examples/blog/index.rb +289 -0
  61. data/opal/fron-ui/examples/comments/components/comment.rb +75 -0
  62. data/opal/fron-ui/examples/comments/components/comments.rb +93 -0
  63. data/opal/fron-ui/examples/comments/components/footer.rb +36 -0
  64. data/opal/fron-ui/examples/comments/components/header.rb +35 -0
  65. data/opal/fron-ui/examples/comments/components/list.rb +12 -0
  66. data/opal/fron-ui/examples/comments/index.rb +6 -0
  67. data/opal/fron-ui/examples/contacts/components/contacts.rb +100 -0
  68. data/opal/fron-ui/examples/contacts/components/details.rb +92 -0
  69. data/opal/fron-ui/examples/contacts/components/item.rb +46 -0
  70. data/opal/fron-ui/examples/contacts/components/list.rb +10 -0
  71. data/opal/fron-ui/examples/contacts/components/sidebar.rb +30 -0
  72. data/opal/fron-ui/examples/contacts/index.rb +6 -0
  73. data/opal/fron-ui/examples/editor/index.rb +164 -0
  74. data/opal/fron-ui/examples/kitchensink/index.rb +193 -0
  75. data/opal/fron-ui/examples/todos/components/item.rb +84 -0
  76. data/opal/fron-ui/examples/todos/components/options.rb +26 -0
  77. data/opal/fron-ui/examples/todos/components/todos.rb +145 -0
  78. data/opal/fron-ui/examples/todos/index.rb +6 -0
  79. data/opal/fron-ui/examples/webshop/index.rb +0 -0
  80. data/opal/fron-ui/fonts/ionicons.rb +2954 -0
  81. data/opal/fron-ui/fonts/open_sans.rb +19 -0
  82. data/opal/fron-ui/lib/collection.rb +138 -0
  83. data/opal/fron-ui/lib/date.rb +23 -0
  84. data/opal/fron-ui/lib/debounce.rb +14 -0
  85. data/opal/fron-ui/lib/image_loader.rb +13 -0
  86. data/opal/fron-ui/lib/lorem.rb +93 -0
  87. data/opal/fron-ui/lib/nil.rb +29 -0
  88. data/opal/fron-ui/lib/record.rb +23 -0
  89. data/opal/fron-ui/lib/state_serializer.rb +129 -0
  90. data/opal/fron-ui/lib/storage.rb +57 -0
  91. data/opal/fron-ui/spec/setup.rb +40 -0
  92. data/opal/fron-ui/ui.rb +40 -0
  93. data/opal/fron-ui/utils/theme_roller.rb +63 -0
  94. data/opal/fron-ui/vendor/autoprefixer.js +21114 -0
  95. data/opal/fron-ui/vendor/marked.js +1291 -0
  96. data/opal/fron-ui/vendor/md5.js +274 -0
  97. data/opal/fron-ui/vendor/moment.js +3083 -0
  98. data/opal/fron-ui/vendor/uuid.js +92 -0
  99. data/opal/fron_ui.rb +13 -0
  100. data/spec/behaviors/action_spec.rb +34 -0
  101. data/spec/behaviors/actions_spec.rb +38 -0
  102. data/spec/behaviors/confirmation_spec.rb +23 -0
  103. data/spec/behaviors/dropdown_spec.rb +32 -0
  104. data/spec/behaviors/render_spec.rb +20 -0
  105. data/spec/behaviors/rest_spec.rb +70 -0
  106. data/spec/behaviors/selectable_children_spec.rb +40 -0
  107. data/spec/behaviors/serialize_spec.rb +34 -0
  108. data/spec/components/action_spec.rb +7 -0
  109. data/spec/components/base_spec.rb +19 -0
  110. data/spec/components/box_spec.rb +7 -0
  111. data/spec/components/button_spec.rb +9 -0
  112. data/spec/components/calendar_spec.rb +58 -0
  113. data/spec/components/checkbox_spec.rb +20 -0
  114. data/spec/components/chooser_spec.rb +75 -0
  115. data/spec/components/color_panel_spec.rb +49 -0
  116. data/spec/components/color_picker_spec.rb +41 -0
  117. data/spec/components/container_spec.rb +23 -0
  118. data/spec/components/date_picker_spec.rb +71 -0
  119. data/spec/components/drag_spec.rb +20 -0
  120. data/spec/components/dropdown_spec.rb +33 -0
  121. data/spec/components/image_spec.rb +33 -0
  122. data/spec/components/input_spec.rb +8 -0
  123. data/spec/components/list_spec.rb +10 -0
  124. data/spec/components/loader_spec.rb +9 -0
  125. data/spec/components/notifications_spec.rb +17 -0
  126. data/spec/components/number_spec.rb +64 -0
  127. data/spec/components/progress_spec.rb +23 -0
  128. data/spec/components/slider_spec.rb +25 -0
  129. data/spec/components/tabs_spec.rb +50 -0
  130. data/spec/components/textarea_spec.rb +7 -0
  131. data/spec/components/time_spec.rb +37 -0
  132. data/spec/components/title_spec.rb +11 -0
  133. data/spec/examples/comments_spec.rb +72 -0
  134. data/spec/examples/todos_spec.rb +39 -0
  135. data/spec/lib/collection_spec.rb +38 -0
  136. data/spec/lib/lorem_spec.rb +55 -0
  137. data/spec/lib/state_serializer_spec.rb +58 -0
  138. data/spec/lib/storage_spec.rb +39 -0
  139. data/spec/spec_helper.rb +1 -0
  140. metadata +223 -0
@@ -0,0 +1,8 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::Input do
4
+ it 'should be an input' do
5
+ subject.tag.should eq :input
6
+ subject[:type].should eq :text
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::List do
4
+ describe '#flex=' do
5
+ it 'should set flex' do
6
+ # Phantomjs cannot work with flex...
7
+ subject.flex = 1
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::Loader do
4
+ describe '#loading' do
5
+ it 'should return false if not loading' do
6
+ subject.loading.should eq false
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::Notifications do
4
+ it 'should display notifications' do
5
+ expect {
6
+ subject.push 'Test'
7
+ }.to change { subject.children.count }.from(0).to(1)
8
+ end
9
+
10
+ it 'should remove notificaion' do
11
+ noti = subject.push 'Test'
12
+ expect {
13
+ noti.trigger :animationend, animationName: 'ui-notification-show'
14
+ noti.trigger :animationend, animationName: 'ui-notification-hide'
15
+ }.to change { noti.parent }.from(subject).to(nil)
16
+ end
17
+ end
@@ -0,0 +1,64 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::NumberRange do
4
+ let(:input) { subject.find('ui-number-range-input') }
5
+
6
+ before do
7
+ allow(subject).to receive(:width).and_return 200
8
+ end
9
+
10
+ it 'should have a default value' do
11
+ subject.value.should eq 0
12
+ end
13
+
14
+ describe '#on_mouse_move' do
15
+ it 'should set the cursor' do
16
+ expect {
17
+ subject.trigger :mousemove, pageX: 10
18
+ }.to change { subject.style.cursor }.from('').to('move')
19
+ end
20
+ end
21
+
22
+ describe '#input' do
23
+ it 'should set placeholder character' do
24
+ expect {
25
+ subject.text = ''
26
+ subject.input
27
+ }.to change { input.html }.from('0.0').to(`'\ufeff'`)
28
+ end
29
+ end
30
+
31
+ describe '#keydown' do
32
+ let(:event) { double key: :enter }
33
+ it 'should prevent the event' do
34
+ event.should receive(:prevent_default)
35
+ subject.keydown event
36
+ end
37
+ end
38
+
39
+ context 'Changing the maximum value' do
40
+ it 'should reset the value' do
41
+ subject.value = 100
42
+ expect {
43
+ subject.max = 10
44
+ }.to change { subject.value }.from(100).to(10)
45
+ end
46
+ end
47
+
48
+ context 'Bluring the input' do
49
+ it 'should set the value' do
50
+ input.text = 10
51
+ expect {
52
+ input.trigger :blur
53
+ }.to change { subject.value }.from(0).to(10)
54
+ end
55
+ end
56
+
57
+ context 'Dragging horizontally' do
58
+ it 'should increase the value' do
59
+ expect {
60
+ mock_drag subject.drag, 10, 10
61
+ }.to change { subject.value }.from(0).to(10)
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::Progress do
4
+ it 'should have a default value' do
5
+ subject.value.should eq 0
6
+ end
7
+
8
+ describe '#value=' do
9
+ it 'should set the value' do
10
+ expect {
11
+ subject.value = 0.1
12
+ }.to change { subject.bar.style.width.to_i }.from(0).to(10)
13
+ end
14
+ end
15
+
16
+ describe '#color=' do
17
+ it 'should set the color' do
18
+ expect {
19
+ subject.color = :red
20
+ }.to change { subject.bar.style.backgroundColor }.to('red')
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::Slider do
4
+ before do
5
+ allow(subject).to receive(:width).and_return 100
6
+ end
7
+
8
+ it 'should have tabindex' do
9
+ subject.tabindex.should eq '0'
10
+ end
11
+
12
+ describe '#value' do
13
+ it 'should return value' do
14
+ subject.value.should eq 0
15
+ end
16
+ end
17
+
18
+ describe '#value=' do
19
+ it 'should set the value' do
20
+ expect {
21
+ subject.value = 0.5
22
+ }.to change { subject.handle.style.left }.from('').to('50px')
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ class Tab < UI::Tabs::Tab
4
+ tag 'div'
5
+ defaults tab_id: 'test',
6
+ tab_title: 'test'
7
+ end
8
+
9
+ class Tab2 < UI::Tabs::Tab
10
+ tag 'div'
11
+ defaults tab_id: 'test2',
12
+ tab_title: 'test2'
13
+ end
14
+
15
+ describe UI::Tabs do
16
+ let(:tab) { Tab.new }
17
+ let(:selected) { subject.find('[tab_id].selected') }
18
+
19
+ before do
20
+ subject << tab
21
+ end
22
+
23
+ it 'should create tabs' do
24
+ subject.insert_before tab, nil
25
+ subject.handles.children.count.should eq 1
26
+ end
27
+
28
+ it 'should select first tab' do
29
+ selected.should_not be_nil
30
+ end
31
+
32
+ context 'Selecting an other tab' do
33
+ it 'should deselect active one' do
34
+ tab2 = Tab2.new
35
+ subject << tab2
36
+ expect {
37
+ subject.select tab2
38
+ }.to change { selected.has_class(:selected) }.from(true).to(false)
39
+ end
40
+ end
41
+
42
+ context 'Removing an tab' do
43
+ it 'should remove the handler' do
44
+ subject
45
+ expect {
46
+ tab.remove!
47
+ }.to change { subject.handles.children.count }.from(1).to(0)
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::Textarea do
4
+ it 'should be an textarea' do
5
+ subject.tag.should eq :textarea
6
+ end
7
+ end
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ module UI
4
+ # Stub timeout so we don't go into recursion
5
+ class Time < Fron::Component
6
+ def timeout
7
+ end
8
+ end
9
+ end
10
+
11
+ describe UI::Time do
12
+ describe '#recall' do
13
+ it 'should call render' do
14
+ subject.should receive(:render)
15
+ subject.should receive(:timeout).and_yield
16
+ subject.recall
17
+ end
18
+ end
19
+
20
+ describe '#value=' do
21
+ it 'should set value' do
22
+ subject.value = Date.parse('2015-01-01')
23
+ subject.text.should eq '2015-01-01'
24
+ end
25
+ end
26
+
27
+ context 'From now' do
28
+ before do
29
+ subject.from_now = true
30
+ subject.render
31
+ end
32
+
33
+ it 'should render time' do
34
+ subject.text.should eq 'a few seconds ago'
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+
3
+ describe UI::Title do
4
+ describe '#align=' do
5
+ it 'should set the align' do
6
+ expect {
7
+ subject.align = :center
8
+ }.to change { subject.style.textAlign }.from('').to(:center)
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,72 @@
1
+ require 'spec_helper'
2
+ require 'fron-ui/examples/comments/components/comments'
3
+
4
+ describe Examples::Comments do
5
+ let(:user) { { name: 'Test Joe', image: '//placehold.it/250/f9f9f9/333' } }
6
+ let(:items) {
7
+ [
8
+ { id: '0', date: Time.now, user: user, body: '<p>test</p>', votes: 0 }
9
+ ]
10
+ }
11
+
12
+ before do
13
+ allow(subject).to receive(:request).with(:get, '').and_yield items
14
+ subject.load
15
+ end
16
+
17
+ let(:comment) { subject.find('ui-comment') }
18
+
19
+ it 'should display comments' do
20
+ comment.should_not be_nil
21
+ end
22
+
23
+ context 'Filling the textarea and clicking on the button' do
24
+ it 'should add a comment' do
25
+ subject.should receive(:request).with(:post,
26
+ '',
27
+ hash_including(body: '<p>testasd</p>')).and_yield
28
+ subject.input.value = 'testasd'
29
+ expect {
30
+ subject.find('[action=add]').trigger :click
31
+ }.to change { subject.input.value }.from('testasd').to(nil)
32
+ end
33
+ end
34
+
35
+ context 'Clicking on reply' do
36
+ it 'should focus the textarea' do
37
+ subject.input.should receive(:focus)
38
+ subject.find('[action=reply]').trigger :click
39
+ end
40
+ end
41
+
42
+ context 'Voting up' do
43
+ let(:item) { comment.find('[action=vote_up]') }
44
+ it 'should increase the count' do
45
+ comment.should receive(:request).with(:patch,
46
+ '0',
47
+ hash_including(votes: 1)).and_yield(items[0].merge(votes: 1))
48
+ expect {
49
+ item.trigger :click
50
+ }.to change { item.label.text }.from('0').to('1')
51
+ end
52
+ end
53
+
54
+ context 'Voting down' do
55
+ let(:item) { comment.find('[action=vote_down]') }
56
+ it 'should decrease the count' do
57
+ comment.should receive(:request).with(:patch,
58
+ '0',
59
+ hash_including(votes: -1)).and_yield(items[0].merge(votes: -1))
60
+ expect {
61
+ item.trigger :click
62
+ }.to change { comment.find('[action=vote_up]').label.text }.from('0').to('-1')
63
+ end
64
+ end
65
+
66
+ context 'Clicking on remove icon' do
67
+ it 'should remove the comment' do
68
+ comment.should receive(:request).with(:delete, '0').and_yield
69
+ comment.find('[action="confirm_destroy!"]').trigger :click
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,39 @@
1
+ require 'spec_helper'
2
+ require 'fron-ui/examples/todos/components/todos'
3
+
4
+ describe Examples::Todos do
5
+ let(:items) { [{ done: false, id: 1, test: 'Todo Item #1' }] }
6
+ let(:item) { subject.find('ui-todo-item') }
7
+
8
+ before do
9
+ allow(subject).to receive(:request).with(:get, '').and_yield items
10
+ subject.refresh
11
+ end
12
+
13
+ it 'should display items' do
14
+ item.should_not be_nil
15
+ end
16
+
17
+ context 'Clicking on item' do
18
+ it 'should destroy it' do
19
+ expect(item).to receive(:request).with(:delete, 1).and_yield
20
+ item.find('[action="confirm_destroy!"]').trigger :click
21
+ end
22
+ end
23
+
24
+ context 'Checking an item' do
25
+ it 'should update it' do
26
+ expect(item).to receive(:request).with(:patch, 1, done: true).and_yield
27
+ item.checkbox.trigger :click
28
+ end
29
+ end
30
+
31
+ context 'Adding an item' do
32
+ it 'should create it' do
33
+ data = hash_including text: 'Test', done: false
34
+ expect(subject).to receive(:request).with(:post, '', data).and_yield
35
+ subject.header.input.value = 'Test'
36
+ subject.header.button.trigger :click
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Collection do
4
+ let(:data) { [{ id: 0 }, { id: 1 }] }
5
+ let(:new_data) { [{ id: 2 }, { id: 0 }, { id: 3 }] }
6
+
7
+ before do
8
+ subject.items = data
9
+ end
10
+
11
+ context 'Initial state' do
12
+ it 'should create items first time' do
13
+ subject.children.count.should eq 2
14
+ end
15
+
16
+ it 'should keep order' do
17
+ subject.items.map { |item| item.data[:id] }.should eq [0, 1]
18
+ end
19
+ end
20
+
21
+ context 'Updated state' do
22
+ let(:item1) { subject.items.find { |item| item.data[:id] == 1 } }
23
+ let(:item0) { subject.items.find { |item| item.data[:id] == 0 } }
24
+ let(:expectation) { expect { subject.items = new_data } }
25
+
26
+ it 'should remove items' do
27
+ expectation.to change { item1.parent }.to nil
28
+ end
29
+
30
+ it 'should reposition items' do
31
+ expectation.to change { item0.index }.from(0).to(1)
32
+ end
33
+
34
+ it 'should add new items' do
35
+ expectation.to change { subject.children.count }.from(2).to(3)
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Lorem do
4
+ subject { described_class }
5
+
6
+ describe '#name' do
7
+ it 'should return a name' do
8
+ first, last = subject.name.split(' ')
9
+ subject::FIRST_NAMES.should include(first)
10
+ subject::LAST_NAMES.should include(last)
11
+ end
12
+ end
13
+
14
+ describe '#paragraph' do
15
+ it 'should return a paragraph' do
16
+ paragraph = subject.paragraph
17
+ paragraph.should start_with('<p>')
18
+ paragraph.should end_with('</p>')
19
+ end
20
+ end
21
+
22
+ describe '#sentence' do
23
+ it 'return a sentence' do
24
+ sentence = subject.sentence((1..1), '?')
25
+ sentence.should end_with('?')
26
+ sentence[0].should match(/[A-Z]/)
27
+ end
28
+ end
29
+
30
+ describe '#sentences' do
31
+ it 'should call sentence count times' do
32
+ subject.should receive(:sentence).twice
33
+ subject.sentences(2)
34
+ end
35
+ end
36
+
37
+ describe '#paragraphs' do
38
+ it 'should call paragraph count times' do
39
+ subject.should receive(:paragraph).twice
40
+ subject.paragraphs(2)
41
+ end
42
+ end
43
+
44
+ describe '#avatar' do
45
+ it 'should return an avatar' do
46
+ subject.avatar('men', 0).should eq 'https://randomuser.me/api/portraits/men/0.jpg'
47
+ end
48
+ end
49
+
50
+ describe '#image' do
51
+ it 'should return an image' do
52
+ subject.image(100, 100).should eq 'http://lorempixum.com/100/100'
53
+ end
54
+ end
55
+ end