coupdoeil 1.0.0.pre.beta.1 → 1.0.0.pre.beta.3

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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +13 -0
  3. data/README.md +25 -21
  4. data/app/assets/javascripts/coupdoeil.js +134 -134
  5. data/app/assets/javascripts/coupdoeil.min.js +1 -1
  6. data/app/assets/javascripts/coupdoeil.min.js.map +1 -1
  7. data/app/assets/stylesheets/coupdoeil/popover-animation.css +44 -0
  8. data/app/assets/stylesheets/coupdoeil/popover-arrow.css +39 -0
  9. data/app/assets/stylesheets/coupdoeil/popover.css +84 -0
  10. data/app/controllers/coupdoeil/{hovercards_controller.rb → popovers_controller.rb} +13 -13
  11. data/app/helpers/coupdoeil/application_helper.rb +2 -9
  12. data/app/javascript/coupdoeil/elements/coupdoeil_element.js +13 -13
  13. data/app/javascript/coupdoeil/events/onclick.js +36 -36
  14. data/app/javascript/coupdoeil/events/onmouseover.js +52 -52
  15. data/app/javascript/coupdoeil/events.js +4 -4
  16. data/app/javascript/coupdoeil/index.js +1 -1
  17. data/app/javascript/coupdoeil/{hovercard → popover}/attributes.js +4 -4
  18. data/app/javascript/coupdoeil/popover/cache.js +22 -0
  19. data/app/javascript/coupdoeil/{hovercard → popover}/closing.js +18 -18
  20. data/app/javascript/coupdoeil/{hovercard → popover}/config.js +6 -6
  21. data/app/javascript/coupdoeil/popover/controller.js +20 -0
  22. data/app/javascript/coupdoeil/popover/current.js +13 -0
  23. data/app/javascript/coupdoeil/{hovercard → popover}/opening.js +27 -27
  24. data/app/javascript/coupdoeil/{hovercard/optionsParser.js → popover/options_parser.js} +22 -10
  25. data/app/javascript/coupdoeil/{hovercard → popover}/positioning.js +2 -2
  26. data/app/javascript/coupdoeil/popover/state_check.js +12 -0
  27. data/app/models/coupdoeil/params.rb +4 -4
  28. data/app/models/coupdoeil/{hovercard → popover}/option/animation.rb +2 -2
  29. data/app/models/coupdoeil/{hovercard → popover}/option/cache.rb +2 -2
  30. data/app/models/coupdoeil/{hovercard → popover}/option/loading.rb +2 -2
  31. data/app/models/coupdoeil/popover/option/offset.rb +48 -0
  32. data/app/models/coupdoeil/{hovercard → popover}/option/opening_delay.rb +2 -2
  33. data/app/models/coupdoeil/{hovercard → popover}/option/placement.rb +2 -2
  34. data/app/models/coupdoeil/{hovercard → popover}/option/trigger.rb +2 -2
  35. data/app/models/coupdoeil/{hovercard → popover}/option.rb +1 -1
  36. data/app/models/coupdoeil/{hovercard → popover}/options_set.rb +14 -9
  37. data/app/models/coupdoeil/{hovercard → popover}/registry.rb +2 -2
  38. data/app/models/coupdoeil/popover/setup.rb +36 -0
  39. data/app/models/coupdoeil/{hovercard → popover}/view_context_delegation.rb +3 -3
  40. data/app/models/coupdoeil/{hovercard.rb → popover.rb} +24 -12
  41. data/app/models/coupdoeil/tag.rb +24 -15
  42. data/app/style/{hovercard-animation.scss → popover-animation.scss} +7 -7
  43. data/app/style/popover-arrow.scss +40 -0
  44. data/app/style/popover.scss +2 -0
  45. data/config/routes.rb +1 -1
  46. data/lib/coupdoeil/engine.rb +8 -8
  47. data/lib/coupdoeil/version.rb +1 -1
  48. data/lib/generators/coupdoeil/install/install_generator.rb +8 -8
  49. data/lib/generators/coupdoeil/install/templates/layout.html.erb.tt +1 -1
  50. data/lib/generators/coupdoeil/popover/USAGE +15 -0
  51. data/lib/generators/coupdoeil/popover/popover_generator.rb +22 -0
  52. data/lib/generators/coupdoeil/{hovercard/templates/hovercard.rb.tt → popover/templates/popover.rb.tt} +1 -1
  53. metadata +40 -40
  54. data/app/assets/stylesheets/coupdoeil/hovercard-animation.css +0 -44
  55. data/app/assets/stylesheets/coupdoeil/hovercard-arrow.css +0 -39
  56. data/app/assets/stylesheets/coupdoeil/hovercard.css +0 -84
  57. data/app/javascript/coupdoeil/hovercard/cache.js +0 -22
  58. data/app/javascript/coupdoeil/hovercard/controller.js +0 -20
  59. data/app/javascript/coupdoeil/hovercard/current.js +0 -13
  60. data/app/javascript/coupdoeil/hovercard/state_check.js +0 -12
  61. data/app/models/coupdoeil/hovercard/option/offset.rb +0 -35
  62. data/app/models/coupdoeil/hovercard/setup.rb +0 -44
  63. data/app/style/hovercard-arrow.scss +0 -40
  64. data/app/style/hovercard.scss +0 -2
  65. data/lib/generators/coupdoeil/hovercard/USAGE +0 -15
  66. data/lib/generators/coupdoeil/hovercard/hovercard_generator.rb +0 -22
  67. /data/app/javascript/coupdoeil/{hovercard → popover}/actions.js +0 -0
  68. /data/app/javascript/coupdoeil/{hovercard.js → popover.js} +0 -0
@@ -1,39 +0,0 @@
1
- .coupdoeil--hovercard [data-hovercard-arrow] {
2
- --co-hovercard--color: white;
3
- --co-hovercard--border-color: rgb(209 213 219);
4
- --co-hovercard-border-size: 1px;
5
- --co-hovercard-border-style: solid;
6
- --co-hovercard--size-ratio: 1;
7
- --co-hovercard--height: 0.75rem;
8
- --co-hovercard--width: calc(var(--co-hovercard--height) / var(--co-hovercard--size-ratio));
9
- position: absolute;
10
- height: var(--co-hovercard--height);
11
- width: var(--co-hovercard--height);
12
- }
13
- .coupdoeil--hovercard [data-hovercard-arrow]::after, .coupdoeil--hovercard [data-hovercard-arrow]::before {
14
- content: "";
15
- width: 0;
16
- height: 0;
17
- position: absolute;
18
- bottom: 0;
19
- border: var(--co-hovercard--base-border-width) var(--co-hovercard-border-style) transparent;
20
- }
21
- .coupdoeil--hovercard [data-hovercard-arrow]::after {
22
- --co-hovercard--base-border-width: var(--co-hovercard--width);
23
- border-bottom-color: var(--co-hovercard--color);
24
- left: calc(50% - var(--co-hovercard--width));
25
- }
26
- .coupdoeil--hovercard [data-hovercard-arrow]::before {
27
- --co-hovercard--base-border-width: calc(var(--co-hovercard--height) + var(--co-hovercard-border-size));
28
- border-bottom-color: var(--co-hovercard--border-color);
29
- left: calc(50% - var(--co-hovercard--width) - var(--co-hovercard-border-size));
30
- }
31
- .coupdoeil--hovercard[data-placement|=top] [data-hovercard-arrow] {
32
- transform: rotate(180deg);
33
- }
34
- .coupdoeil--hovercard[data-placement|=right] [data-hovercard-arrow] {
35
- transform: rotate(-90deg);
36
- }
37
- .coupdoeil--hovercard[data-placement|=left] [data-hovercard-arrow] {
38
- transform: rotate(90deg);
39
- }
@@ -1,84 +0,0 @@
1
- .coupdoeil--hovercard.hidden {
2
- display: none;
3
- }
4
-
5
- .coupdoeil--hovercard[data-animation].hovercard-enter {
6
- transition-timing-function: cubic-bezier(0.4, 0, 1, 1);
7
- }
8
- .coupdoeil--hovercard[data-animation].hovercard-leave {
9
- transition-timing-function: cubic-bezier(0, 0, 0.2, 1);
10
- }
11
- .coupdoeil--hovercard[data-animation].hovercard-enter, .coupdoeil--hovercard[data-animation].hovercard-leave {
12
- transition-property: opacity, transform;
13
- transition-duration: 150ms;
14
- }
15
- .coupdoeil--hovercard[data-animation].hovercard-enter-end[data-animation=fade-in], .coupdoeil--hovercard[data-animation].hovercard-enter-end[data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-enter-end[data-animation=slide-out], .coupdoeil--hovercard[data-animation].hovercard-leave-start[data-animation=fade-in], .coupdoeil--hovercard[data-animation].hovercard-leave-start[data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-leave-start[data-animation=slide-out] {
16
- opacity: 1;
17
- }
18
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-animation=fade-in], .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-animation=slide-out], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-animation=fade-in], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-animation=slide-out] {
19
- opacity: 0;
20
- }
21
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=right][data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=right][data-animation=slide-in] {
22
- transform: translateX(1rem);
23
- }
24
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=right][data-animation=slide-out], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=right][data-animation=slide-out] {
25
- transform: translateX(-1rem);
26
- }
27
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=left][data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=left][data-animation=slide-in] {
28
- transform: translateX(-1rem);
29
- }
30
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=left][data-animation=slide-out], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=left][data-animation=slide-out] {
31
- transform: translateX(1rem);
32
- }
33
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=top][data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=top][data-animation=slide-in] {
34
- transform: translateY(-1rem);
35
- }
36
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=top][data-animation=slide-out], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=top][data-animation=slide-out] {
37
- transform: translateY(1rem);
38
- }
39
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=bottom][data-animation=slide-in], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=bottom][data-animation=slide-in] {
40
- transform: translateY(1rem);
41
- }
42
- .coupdoeil--hovercard[data-animation].hovercard-enter-start[data-placement|=bottom][data-animation=slide-out], .coupdoeil--hovercard[data-animation].hovercard-leave-end[data-placement|=bottom][data-animation=slide-out] {
43
- transform: translateY(-1rem);
44
- }
45
-
46
- .coupdoeil--hovercard [data-hovercard-arrow] {
47
- --co-hovercard--color: white;
48
- --co-hovercard--border-color: rgb(209 213 219);
49
- --co-hovercard-border-size: 1px;
50
- --co-hovercard-border-style: solid;
51
- --co-hovercard--size-ratio: 1;
52
- --co-hovercard--height: 0.75rem;
53
- --co-hovercard--width: calc(var(--co-hovercard--height) / var(--co-hovercard--size-ratio));
54
- position: absolute;
55
- height: var(--co-hovercard--height);
56
- width: var(--co-hovercard--height);
57
- }
58
- .coupdoeil--hovercard [data-hovercard-arrow]::after, .coupdoeil--hovercard [data-hovercard-arrow]::before {
59
- content: "";
60
- width: 0;
61
- height: 0;
62
- position: absolute;
63
- bottom: 0;
64
- border: var(--co-hovercard--base-border-width) var(--co-hovercard-border-style) transparent;
65
- }
66
- .coupdoeil--hovercard [data-hovercard-arrow]::after {
67
- --co-hovercard--base-border-width: var(--co-hovercard--width);
68
- border-bottom-color: var(--co-hovercard--color);
69
- left: calc(50% - var(--co-hovercard--width));
70
- }
71
- .coupdoeil--hovercard [data-hovercard-arrow]::before {
72
- --co-hovercard--base-border-width: calc(var(--co-hovercard--height) + var(--co-hovercard-border-size));
73
- border-bottom-color: var(--co-hovercard--border-color);
74
- left: calc(50% - var(--co-hovercard--width) - var(--co-hovercard-border-size));
75
- }
76
- .coupdoeil--hovercard[data-placement|=top] [data-hovercard-arrow] {
77
- transform: rotate(180deg);
78
- }
79
- .coupdoeil--hovercard[data-placement|=right] [data-hovercard-arrow] {
80
- transform: rotate(-90deg);
81
- }
82
- .coupdoeil--hovercard[data-placement|=left] [data-hovercard-arrow] {
83
- transform: rotate(90deg);
84
- }
@@ -1,22 +0,0 @@
1
- import {getParams, getType, preloadedContentElement} from './attributes'
2
-
3
- export const hovercardContentHTMLMap = new Map()
4
-
5
- function cacheMapKey(controller) {
6
- if (preloadedContentElement(controller)) {
7
- return controller.coupdoeilElement.uniqueId
8
- }
9
- return getType(controller) + getParams(controller)
10
- }
11
-
12
- export function getHovercardContentHTML(controller) {
13
- return hovercardContentHTMLMap.get(cacheMapKey(controller))
14
- }
15
-
16
- export function setHovercardContentHTML(controller, value) {
17
- hovercardContentHTMLMap.set(cacheMapKey(controller), value)
18
- }
19
-
20
- export function clearHovercardContentCache() {
21
- hovercardContentHTMLMap.clear()
22
- }
@@ -1,20 +0,0 @@
1
- export class HovercardController {
2
- constructor(coupdoeilElement) {
3
- this.coupdoeilElement = coupdoeilElement
4
-
5
- this.card = null // can go on coupdoeil element, renamed 'hovercardElement'
6
-
7
- this.children = new Set() // can go on hovercardElement
8
- this.parent = null // can go on hovercardElement
9
-
10
- this.closingRequest = null // can go on coupdoeil element
11
- }
12
-
13
- get isOpen() {
14
- return !!this.coupdoeilElement.dataset.hovercardOpen
15
- }
16
-
17
- get isClosed() {
18
- return !this.isOpen
19
- }
20
- }
@@ -1,13 +0,0 @@
1
- export const CURRENT_HOVERCARDS_BY_ID = new Map()
2
-
3
- export function currentHovercardsById() {
4
- return CURRENT_HOVERCARDS_BY_ID
5
- }
6
-
7
- export function addToCurrents(coupdoeilElement) {
8
- CURRENT_HOVERCARDS_BY_ID.set(coupdoeilElement.uniqueId, coupdoeilElement)
9
- }
10
-
11
- export function removeFromCurrents(coupdoeilElement) {
12
- CURRENT_HOVERCARDS_BY_ID.delete(coupdoeilElement.uniqueId)
13
- }
@@ -1,12 +0,0 @@
1
- import {HOVERCARD_CLOSE_BTN_SELECTOR} from "./config";
2
-
3
- import {currentHovercardsById} from "./current";
4
-
5
- export function isElementCloseHovercardButton(element) {
6
- return element.closest(HOVERCARD_CLOSE_BTN_SELECTOR) ||
7
- element.dataset.hasOwnProperty("hovercardClose")
8
- }
9
-
10
- export function isAnyHovercardOpened() {
11
- return currentHovercardsById().size > 0
12
- }
@@ -1,35 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coupdoeil
4
- class Hovercard
5
- class Option
6
- class Offset < Coupdoeil::Hovercard::Option
7
- self.bit_size = 8 + 11 + 2
8
-
9
- class << self
10
- def parse(value)
11
- float_value = value.to_f
12
- return 0 if float_value.zero?
13
-
14
- base = 0
15
- base |= 1 if float_value.negative?
16
- base |= 2 if value.is_a?(String) && value.end_with?("rem")
17
-
18
- integer, decimals = float_value.abs.to_s.split(".")
19
- base |= (decimals.to_i << 2)
20
- base |= (integer.to_i << 2 + 11)
21
-
22
- base
23
- end
24
- end
25
-
26
- def validate!
27
- return if value in Float | Integer
28
- return if value.to_s.match?(/^-?\d+(\.\d{1,3})?(px|rem)?$/)
29
-
30
- raise_invalid_option "Value should be a signed float or integer, followed or not by 'rem' or 'px'."
31
- end
32
- end
33
- end
34
- end
35
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Coupdoeil
4
- class Hovercard
5
- class Setup
6
- attr_reader :klass, :type, :params
7
-
8
- EMPTY_PARAMS = {}.freeze
9
-
10
- def initialize(klass)
11
- @klass = klass
12
- @type = nil
13
- @params = EMPTY_PARAMS
14
- end
15
-
16
- def default_options = klass.default_options_for(type)
17
- def identifier = "#{type}@#{klass.hovercard_resource_name}"
18
- def render_in(view_context) = klass.new(params, view_context).process(type)
19
-
20
- def with_type(type)
21
- @type = type
22
- self
23
- end
24
-
25
- def with_params(**params)
26
- @params = params
27
- self
28
- end
29
-
30
- def method_missing(method_name, *args, &)
31
- if klass.action_methods.include?(method_name.name)
32
- raise ArgumentError, "expected no arguments, given #{args.size}" if args.any?
33
- with_type(method_name)
34
- else
35
- super
36
- end
37
- end
38
-
39
- def respond_to_missing?(method, include_all = false)
40
- klass.action_methods.include?(method.name) || super
41
- end
42
- end
43
- end
44
- end
@@ -1,40 +0,0 @@
1
- @use 'sass:list';
2
-
3
- .coupdoeil--hovercard {
4
- & [data-hovercard-arrow] {
5
- --co-hovercard--color: white;
6
- --co-hovercard--border-color: rgb(209 213 219);
7
- --co-hovercard-border-size: 1px;
8
- --co-hovercard-border-style: solid;
9
- --co-hovercard--size-ratio: 1;
10
- --co-hovercard--height: 0.75rem;
11
- --co-hovercard--width: calc(var(--co-hovercard--height) / var(--co-hovercard--size-ratio));
12
-
13
- position: absolute;
14
- height: var(--co-hovercard--height);
15
- width: var(--co-hovercard--height);
16
-
17
- &::after, &::before {
18
- content: "";
19
- width: 0;
20
- height: 0;
21
- position: absolute;
22
- bottom: 0;
23
- border: var(--co-hovercard--base-border-width) var(--co-hovercard-border-style) transparent;
24
- }
25
-
26
- &::after {
27
- --co-hovercard--base-border-width: var(--co-hovercard--width);
28
- border-bottom-color: var(--co-hovercard--color);
29
- left: calc(50% - var(--co-hovercard--width));
30
- }
31
- &::before {
32
- --co-hovercard--base-border-width: calc(var(--co-hovercard--height) + var(--co-hovercard-border-size));
33
- border-bottom-color: var(--co-hovercard--border-color);
34
- left: calc(50% - var(--co-hovercard--width) - var(--co-hovercard-border-size));
35
- }
36
- }
37
- &[data-placement|="top"] [data-hovercard-arrow] { transform: rotate(180deg); }
38
- &[data-placement|="right"] [data-hovercard-arrow] { transform: rotate(-90deg); }
39
- &[data-placement|="left"] [data-hovercard-arrow] { transform: rotate(90deg); }
40
- }
@@ -1,2 +0,0 @@
1
- @use "hovercard-animation";
2
- @use "hovercard-arrow";
@@ -1,15 +0,0 @@
1
- Description:
2
- Create hovercard class and views files.
3
-
4
- Example:
5
- bin/rails generate hovercard Contact details from_project
6
-
7
- creates the following files:
8
- app/hovercards/contact_hovercard.rb
9
- app/views/contact_hovercard/details.html.erb
10
- app/views/contact_hovercard/from_project.html.erb
11
-
12
- bin/rails generate hovercard Contact details from_project --skip-views
13
-
14
- creates only the class file:
15
- app/hovercards/contact_hovercard.rb
@@ -1,22 +0,0 @@
1
- class Coupdoeil::HovercardGenerator < Rails::Generators::NamedBase
2
- source_root File.expand_path("templates", __dir__)
3
-
4
- check_class_collision suffix: "Hovercard"
5
-
6
- class_option :skip_views, type: :boolean, desc: "Skip view files", default: false
7
-
8
- argument :action_names, type: :array, default: []
9
-
10
- def create_hovercard_file
11
- template "hovercard.rb",
12
- File.join("app/hovercards", class_path, "#{file_name}_hovercard.rb")
13
- unless options.skip_views?
14
- action_names.each do |action_name|
15
- path = [*class_path, file_name].join('/')
16
- create_file "app/hovercards/#{path}_hovercard/#{action_name}.html.erb", <<~ERB
17
- <p>Hello from #{class_name}Hovercard##{action_name}</p>
18
- ERB
19
- end
20
- end
21
- end
22
- end