fron-ui 1.0.0rc2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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