ariadne_view_components 0.0.47-x64-mingw-ucrt → 0.0.49-x64-mingw-ucrt

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +29 -25
  3. data/app/assets/javascripts/ariadne_view_components.js +2 -2
  4. data/app/assets/javascripts/ariadne_view_components.js.map +1 -1
  5. data/app/assets/javascripts/components/ariadne/accumulator_controller/accumulator_controller.d.ts +22 -0
  6. data/app/assets/javascripts/components/ariadne/dropdown/menu_component.d.ts +1 -0
  7. data/app/assets/javascripts/components/ariadne/events_controller/events_controller.d.ts +4 -0
  8. data/app/assets/javascripts/components/ariadne/options_controller/options_controller.d.ts +40 -0
  9. data/app/assets/javascripts/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
  10. data/app/assets/javascripts/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
  11. data/app/assets/javascripts/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
  12. data/app/assets/javascripts/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
  13. data/app/assets/stylesheets/ariadne_view_components.css +3 -3
  14. data/app/components/ariadne/accumulator_controller/accumulator_controller.d.ts +22 -0
  15. data/app/components/ariadne/accumulator_controller/accumulator_controller.js +39 -0
  16. data/app/components/ariadne/accumulator_controller/accumulator_controller.ts +48 -0
  17. data/app/components/ariadne/action_card_component.html.erb +11 -0
  18. data/app/components/ariadne/action_card_component.rb +45 -0
  19. data/app/components/ariadne/ariadne.js +10 -0
  20. data/app/components/ariadne/ariadne.ts +10 -0
  21. data/app/components/ariadne/bottom_tab_component.html.erb +4 -0
  22. data/app/components/ariadne/bottom_tab_component.rb +44 -0
  23. data/app/components/ariadne/bottom_tab_nav_component.html.erb +5 -0
  24. data/app/components/ariadne/bottom_tab_nav_component.rb +33 -0
  25. data/app/components/ariadne/breadcrumbs_component.html.erb +13 -0
  26. data/app/components/ariadne/breadcrumbs_component.rb +31 -0
  27. data/app/components/ariadne/checkbox_component.html.erb +5 -0
  28. data/app/components/ariadne/checkbox_component.rb +43 -0
  29. data/app/components/ariadne/close_button_component.html.erb +4 -0
  30. data/app/components/ariadne/close_button_component.rb +33 -0
  31. data/app/components/ariadne/combobox_component.html.erb +14 -0
  32. data/app/components/ariadne/combobox_component.rb +76 -0
  33. data/app/components/ariadne/dropdown/menu_component.d.ts +1 -0
  34. data/app/components/ariadne/dropdown/menu_component.js +1 -0
  35. data/app/components/ariadne/events_controller/events_controller.d.ts +4 -0
  36. data/app/components/ariadne/events_controller/events_controller.js +6 -0
  37. data/app/components/ariadne/events_controller/events_controller.ts +7 -0
  38. data/app/components/ariadne/layout_component.html.erb +21 -0
  39. data/app/components/ariadne/layout_component.rb +69 -0
  40. data/app/components/ariadne/modal_component.html.erb +11 -0
  41. data/app/components/ariadne/modal_component.rb +88 -0
  42. data/app/components/ariadne/options_controller/options_controller.d.ts +40 -0
  43. data/app/components/ariadne/options_controller/options_controller.js +98 -0
  44. data/app/components/ariadne/options_controller/options_controller.ts +132 -0
  45. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.d.ts +42 -0
  46. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.js +237 -0
  47. data/app/components/ariadne/outlet_manager_controller/outlet_manager_controller.ts +278 -0
  48. data/app/components/ariadne/popover_component.html.erb +10 -0
  49. data/app/components/ariadne/popover_component.rb +81 -0
  50. data/app/components/ariadne/progress_bar_component.html.erb +5 -0
  51. data/app/components/ariadne/progress_bar_component.rb +63 -0
  52. data/app/components/ariadne/relative_time_component.html.erb +3 -0
  53. data/app/components/ariadne/relative_time_component.rb +61 -0
  54. data/app/components/ariadne/show_more_button_component.html.erb +11 -0
  55. data/app/components/ariadne/show_more_button_component.rb +47 -0
  56. data/app/components/ariadne/spinner_component.html.erb +16 -0
  57. data/app/components/ariadne/spinner_component.rb +45 -0
  58. data/app/components/ariadne/string_match_controller/string_match_controller.d.ts +27 -0
  59. data/app/components/ariadne/string_match_controller/string_match_controller.js +51 -0
  60. data/app/components/ariadne/string_match_controller/string_match_controller.ts +64 -0
  61. data/app/components/ariadne/subheader_component.html.erb +11 -0
  62. data/app/components/ariadne/subheader_component.rb +65 -0
  63. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.d.ts +44 -0
  64. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.js +153 -0
  65. data/app/components/ariadne/synced_boolean_attributes_controller/synced_boolean_attributes_controller.ts +192 -0
  66. data/app/components/ariadne/toggle_component/toggle_component.html.erb +15 -0
  67. data/app/components/ariadne/toggle_component.rb +95 -0
  68. data/app/components/ariadne/toggleable_controller/toggleable_controller.d.ts +34 -0
  69. data/app/components/ariadne/toggleable_controller/toggleable_controller.js +54 -0
  70. data/app/components/ariadne/toggleable_controller/toggleable_controller.ts +77 -0
  71. data/lib/ariadne/view_components/version.rb +1 -1
  72. data/static/arguments.yml +50 -0
  73. data/static/audited_at.json +17 -0
  74. data/static/classes.yml +209 -173
  75. data/static/constants.json +356 -0
  76. data/static/statuses.json +17 -0
  77. data/tailwind.config.js +7 -7
  78. metadata +75 -12
  79. /data/app/assets/javascripts/{ariadne-form.d.ts → components/ariadne/ariadne-form.d.ts} +0 -0
  80. /data/app/assets/javascripts/{ariadne.d.ts → components/ariadne/ariadne.d.ts} +0 -0
  81. /data/app/assets/javascripts/{clipboard_copy_component → components/ariadne/clipboard_copy_component}/clipboard-copy-component.d.ts +0 -0
  82. /data/app/assets/javascripts/{rich_text_area_component → components/ariadne/rich_text_area_component}/rich-text-area-component.d.ts +0 -0
  83. /data/app/assets/javascripts/{slideover_component → components/ariadne/slideover_component}/slideover-component.d.ts +0 -0
  84. /data/app/assets/javascripts/{tab_container_component → components/ariadne/tab_container_component}/tab-container-component.d.ts +0 -0
  85. /data/app/assets/javascripts/{tab_nav_component → components/ariadne/tab_nav_component}/tab-nav-component.d.ts +0 -0
  86. /data/app/assets/javascripts/{time_ago_component → components/ariadne/time_ago_component}/time-ago-component.d.ts +0 -0
  87. /data/app/assets/javascripts/{tooltip_component → components/ariadne/tooltip_component}/tooltip-component.d.ts +0 -0
@@ -0,0 +1,192 @@
1
+ import OutletManagerController from '../outlet_manager_controller/outlet_manager_controller'
2
+
3
+ export type TStimulusDispatchEvent<TDetails> = {
4
+ target?: Element | undefined
5
+ detail?: TDetails | undefined
6
+ prefix?: string | undefined
7
+ bubbles?: boolean | undefined
8
+ cancelable?: boolean | undefined
9
+ preventDefault: () => void
10
+ }
11
+
12
+ export type TBooleanValueDetail = {
13
+ value: boolean
14
+ }
15
+
16
+ export interface TSyncAttrDetail extends TBooleanValueDetail {
17
+ attr: string
18
+ }
19
+
20
+ /*
21
+ This class isn't used directly by itself because it has no functionality. What it does is establishes
22
+ "synced attrs" and "anti-attrs" so that other controllers can extend this one and not worry about
23
+ implementing the logic themselves (and thus have duplicate logic all over our controllers)
24
+
25
+ To implement this, extend your controller with "SyncedBooleanAttributesController" then spread its
26
+ values into your controllers then implement:
27
+
28
+ export default class MyNewController extends SyncedBooleanAttributesController {
29
+ static values = {
30
+ ...SyncedBooleanAttributesController.values,
31
+ myString: String,
32
+ }
33
+ }
34
+
35
+ Also, consider the functions defined here ABOVE the connection() function. Those functions will
36
+ give you control over how your controller can interact with other SyncedBooleanAttributeControllers.
37
+ Not every controller needs them but you should consider them (description can be found in the functions)
38
+
39
+ And don't forget that when you want to change an attr on an element, you should not do it manually.
40
+ Instead run:
41
+ this.updateAttributesForElement(element, value)
42
+ This will let you take advantage of the ecosystem created by this base controller without any additional work
43
+ */
44
+
45
+ export default class SyncedBooleanAttributesController<T> extends OutletManagerController<T> {
46
+ static values = {
47
+ ...OutletManagerController.values,
48
+ syncedAttrs: Array, // Set option target attrs to true/false in agreement with the option's selected state
49
+ antiAttrs: Array, // Set option target attrs to true/false opposite of the option's selected state
50
+ protectAttrs: Boolean, // If the controller should block other SyncedBooleanAttributesController from changing its defined attrs
51
+ }
52
+
53
+ declare readonly syncedAttrsValue: string[]
54
+ declare readonly hasSyncedAttrsValue: boolean
55
+ declare readonly antiAttrsValue: string[]
56
+ declare readonly hasAntiAttrsValue: boolean
57
+ declare readonly protectAttrsValue: boolean
58
+
59
+ // Some attributes are only false in HTML if they don't exist
60
+ // If included here, the property will be deleted on "false"
61
+ static removeOnFalseAttrs: {[k: string]: boolean} = {
62
+ checked: true,
63
+ }
64
+
65
+ syncedAttrsLookup: {[k: string]: boolean} | null = null
66
+ antiAttrsLookup: {[k: string]: boolean} | null = null
67
+
68
+ getValueForElement(element: Element): boolean | null {
69
+ // This function allows the base controller to access a given element's
70
+ // current status so the attributes can be set or compared. For example,
71
+ // you will want to make sure the attributes are added initially and are
72
+ // in sync with the controller's state. To ensure this, you can use the
73
+ // default connect() function or add "this.syncElementAttributes()" to your
74
+ // custom connect function. It'll look through your targets and get values for
75
+ // each then set the appropriate attrs and anti-attrs
76
+ return null
77
+ }
78
+
79
+ getElementsToSync(): Array<Element> | null | undefined {
80
+ // These are the elements your controller wants to keep in sync with the attrs
81
+ // Sometimes these are this.element, sometimes they're specific targets.
82
+ // Return them here so the base controller can automate some behaviors for you
83
+ return []
84
+ }
85
+
86
+ connect(): void {
87
+ // This function will sync attrs and anti-attrs when the controller connects.
88
+ // The logic is abstracted to a function so you can override this connect
89
+ // function in favor of your own without having to duplicate the sync logic
90
+ this.syncElementAttributes()
91
+ }
92
+
93
+ updateAttributesForElement(element: Element, value: boolean) {
94
+ // This is how you should update any synced or anti-synced attrs on your elements
95
+ // Do not do it manually unless you are very sure of what you're doing
96
+ if (this.hasSyncedAttrsValue) {
97
+ this.#setAttrs(element, this.syncedAttrsValue, value)
98
+ }
99
+
100
+ if (this.hasAntiAttrsValue) {
101
+ this.#setAttrs(element, this.antiAttrsValue, !value)
102
+ }
103
+ }
104
+
105
+ syncElementAttributes() {
106
+ this.syncOutlets()
107
+ // Essentially just a "sync attrs and anti-attrs on mount" function
108
+ const elements = this.getElementsToSync()
109
+
110
+ if (elements?.length) {
111
+ for (let index in elements) {
112
+ const element = elements[index]
113
+ const value = this.getValueForElement(element) ?? false
114
+ this.updateAttributesForElement(element, value)
115
+ }
116
+ }
117
+ }
118
+
119
+ validateAttrChange(dispatchEvent: TStimulusDispatchEvent<TSyncAttrDetail>) {
120
+ // If you protect your attrs, then this function will deny other controllers you specify from making changes to them.
121
+ // For example, if you want an item to disappear when it's selected, then your Options controller likely has an "aria-hidden"
122
+ // synced attr. If you use another attr to filter the list and then remove that filter, normally that would unhide your selected
123
+ // element. But if you have Options protect its attrs, the filter behavior won't be allowed to change it at any time and thus
124
+ // the element will remain hidden
125
+ const {target, detail} = dispatchEvent
126
+ if (target && detail) {
127
+ const currentValue = this.getValueForElement(target)
128
+ if (currentValue !== null && this.protectAttrsValue && this.#isAttr(detail.attr)) {
129
+ dispatchEvent.preventDefault()
130
+ }
131
+ }
132
+ }
133
+
134
+ #isSyncedAttr(attr: string) {
135
+ // Helper function to determine if the attr is synced
136
+ if (this.syncedAttrsLookup === null) {
137
+ this.syncedAttrsLookup = this.#getLookupForStringArray(this.syncedAttrsValue)
138
+ }
139
+
140
+ return this.syncedAttrsLookup[attr] ?? false
141
+ }
142
+
143
+ #isAntiAttr(attr: string) {
144
+ // Helper function to determine if the attr is anti-synced
145
+ if (this.antiAttrsLookup === null) {
146
+ this.antiAttrsLookup = this.#getLookupForStringArray(this.antiAttrsValue)
147
+ }
148
+
149
+ return this.antiAttrsLookup[attr] ?? false
150
+ }
151
+
152
+ #isAttr(attr: string) {
153
+ // Helper function to determine if an attr is known to a controller
154
+ return this.#isAntiAttr(attr) || this.#isSyncedAttr(attr)
155
+ }
156
+
157
+ #setAttrs(element: Element, attrs: string[], value: boolean) {
158
+ // Attempts to change the attr for an element. However, it'll dispatch an event
159
+ // first so other controllers get the opportunity to deny it
160
+ const attrState = JSON.stringify(value)
161
+ for (let index in attrs) {
162
+ const attr = attrs[index]
163
+
164
+ const dispatchEvent = this.dispatch('attrChange', {
165
+ target: element,
166
+ detail: {attr, value},
167
+ } as TStimulusDispatchEvent<TSyncAttrDetail>)
168
+
169
+ if (!dispatchEvent.defaultPrevented) {
170
+ if (attrState === 'false' && SyncedBooleanAttributesController.removeOnFalseAttrs[attr]) {
171
+ element.removeAttribute(attr)
172
+ } else {
173
+ element.setAttribute(attr, attrState)
174
+ }
175
+ }
176
+ }
177
+ }
178
+
179
+ #getLookupForStringArray(arr?: Array<string>) {
180
+ // Helper function to return an array of strings into an object for easy lookup
181
+ // While the arrays contained here are small, looking up attrs will happen often
182
+ // so I think it's worth the small sacrifice to memory
183
+ if (!arr?.length) {
184
+ return {}
185
+ }
186
+
187
+ return arr.reduce((acc, cur) => {
188
+ acc[cur] = true
189
+ return acc
190
+ }, {} as {[k: string]: boolean})
191
+ }
192
+ }
@@ -0,0 +1,15 @@
1
+ <%= render Ariadne::BaseComponent.new(tag: @tag, classes: @classes, attributes: @attributes) do |wrapper| %>
2
+ <label class="ariadne-flex ariadne-w-fit ariadne-items-center <%= @label_classes %>">
3
+ <% if content? %>
4
+ <span class="group-data-[label-position=start]/wrapper:ariadne-mr-1.5 group-data-[label-position=end]/wrapper:ariadne-ml-1"><%= content %></span>
5
+ <% end %>
6
+ <%= render Ariadne::BaseComponent.new(tag: :button, classes: @button_classes, attributes: @button_attributes) do |button| %>
7
+ <span class="ariadne-sr-only ariadne-translate-x-3">Use setting</span>
8
+ <span aria-hidden="true" class="ariadne-pointer-events-none ariadne-absolute ariadne-h-full ariadne-w-full ariadne-rounded-md ariadne-bg-white"></span>
9
+ <span aria-hidden="true"
10
+ class="ariadne-bg-gray-200 ariadne-pointer-events-none ariadne-absolute ariadne-mx-auto ariadne-rounded-full ariadne-transition-colors ariadne-duration-200 ariadne-ease-in-out <%= @track_classes %>"></span>
11
+ <span aria-hidden="true"
12
+ class="ariadne-pointer-events-none ariadne-absolute ariadne-left-0 ariadne-inline-block ariadne-transform ariadne-rounded-full ariadne-border ariadne-border-gray-200 ariadne-bg-white ariadne-shadow ariadne-ring-0 ariadne-transition-transform ariadne-duration-200 ariadne-ease-in-out <%= @thumb_classes %>"></span>
13
+ <% end %>
14
+ </label>
15
+ <% end %>
@@ -0,0 +1,95 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Ariadne
4
+ # Simple toggle switch with on/off state. The logic is controlled by toggleable_controller and styles applied through
5
+ # tailwind's group+data attributes: https://tailwindcss.com/docs/hover-focus-and-other-states#data-attributes
6
+ class ToggleComponent < Ariadne::Component
7
+ DEFAULT_TAG = :div
8
+
9
+ DEFAULT_STATUS_LABEL_POSITION = :start
10
+ STATUS_LABEL_POSITION_MAPPINGS = {
11
+ start: "ariadne-flex-row",
12
+ end: "ariadne-flex-row-reverse",
13
+ }.freeze
14
+ STATUS_LABEL_POSITION_OPTIONS = STATUS_LABEL_POSITION_MAPPINGS.keys.freeze
15
+
16
+ DEFAULT_SIZE = :md
17
+ THUMB_SIZE_MAPPINGS = { sm: "ariadne-translate-x-0 ariadne-h-3 ariadne-w-3 group-aria-checked/toggle:ariadne-translate-x-3", md: "ariadne-translate-x-0 ariadne-h-5 ariadne-w-5 group-aria-checked/toggle:ariadne-translate-x-5" }.freeze
18
+ TRACK_SIZE_MAPPINGS = { sm: "ariadne-h-2 ariadne-w-4", md: "ariadne-h-4 ariadne-w-9" }.freeze
19
+ BUTTON_SIZE_MAPPINGS = { sm: "ariadne-h-3 ariadne-w-6", md: "ariadne-h-5 ariadne-w-10" }.freeze
20
+ LABEL_SIZE_MAPPINGS = { sm: "ariadne-text-xs", md: "ariadne-text-lg" }.freeze
21
+ SIZE_OPTIONS = THUMB_SIZE_MAPPINGS.keys.freeze
22
+
23
+ DEFAULT_CLASSES = {
24
+ wrapper: "ariadne-group/wrapper data-[disabled=true]:ariadne-opacity-50 data-[disabled=true]:ariadne-cursor-auto",
25
+ button: "ariadne-flex ariadne-justify-center ariadne-group/toggle ariadne-relative ariadne-inline-flex ariadne-flex-shrink-0 group-data-[disabled=false]/wrapper:ariadne-cursor-pointer ariadne-items-center ariadne-justify-center ariadne-rounded-full ariadne-focus:outline-none ariadne-focus:ring-2 ariadne-focus:ring-indigo-600 ariadne-focus:ring-offset-2 disabled:ariadne-cursor-auto",
26
+ }
27
+
28
+ DEFAULT_ATTRIBUTES = {
29
+ wrapper: {}.freeze,
30
+ button: {
31
+ role: "switch",
32
+ "data-controller": "toggleable",
33
+ "data-toggleable-synced-attrs-value": '["aria-checked"]',
34
+ "data-action": "click->toggleable#toggle",
35
+ },
36
+ }.freeze
37
+
38
+ DEFAULT_TRACK_COLOR = :indigo
39
+ TRACK_COLOR_MAPPINGS = {
40
+ white: "group-aria-checked/toggle:ariadne-bg-white",
41
+ green: "group-aria-checked/toggle:ariadne-bg-green-600",
42
+ blue: "group-aria-checked/toggle:ariadne-bg-blue-600",
43
+ billy_purple: "group-aria-checked/toggle:ariadne-bg-billy-purple",
44
+ indigo: "group-aria-checked/toggle:ariadne-bg-indigo-600",
45
+ }
46
+ TRACK_COLOR_OPTIONS = TRACK_COLOR_MAPPINGS.keys.freeze
47
+
48
+ # @example Default
49
+ #
50
+ # <%= render(Ariadne::ToggleComponent.new) { "Example" } %>
51
+ #
52
+ # @param classes [String] <%= link_to_classes_docs %>
53
+ # @param color [String] <%= link_to_classes_docs %>
54
+ # @param checked [Boolean] <%= link_to_classes_docs %>
55
+ # @param disabled [Boolean] <%= link_to_classes_docs %>
56
+ # @param size [String] <%= link_to_classes_docs %>
57
+ # @param label [String] <%= link_to_classes_docs %>
58
+ # @param status_label_position [String] <%= link_to_classes_docs %>
59
+ # @param attributes [Hash] <%= link_to_attributes_docs %>
60
+ def initialize(
61
+ classes: nil,
62
+ checked: false,
63
+ disabled: false,
64
+ size: DEFAULT_SIZE,
65
+ color: DEFAULT_TRACK_COLOR,
66
+ status_label_position: DEFAULT_STATUS_LABEL_POSITION,
67
+ attributes: {}
68
+ )
69
+ @tag = DEFAULT_TAG
70
+ @size = fetch_or_raise(SIZE_OPTIONS, size)
71
+ @status_label_position = fetch_or_raise(STATUS_LABEL_POSITION_OPTIONS, status_label_position)
72
+ @color = fetch_or_raise(TRACK_COLOR_OPTIONS, color)
73
+ @classes = merge_class_names(DEFAULT_CLASSES[:wrapper], classes)
74
+ @checked = checked
75
+ @disabled = disabled
76
+ @attributes = DEFAULT_ATTRIBUTES[:wrapper].merge({ "data-label-position": @status_label_position, "data-disabled": @disabled }).merge(attributes)
77
+
78
+ @label_classes = merge_class_names(STATUS_LABEL_POSITION_MAPPINGS.fetch(@status_label_position), LABEL_SIZE_MAPPINGS.fetch(@size))
79
+
80
+ @button_classes = merge_class_names(DEFAULT_CLASSES[:button], BUTTON_SIZE_MAPPINGS.fetch(@size))
81
+ @button_attributes = DEFAULT_ATTRIBUTES[:button].merge({ "aria-checked": @checked, "data-toggleable-state-value": @checked, disabled: @disabled })
82
+
83
+ @thumb_classes = THUMB_SIZE_MAPPINGS.fetch(@size)
84
+ @track_classes = merge_class_names(TRACK_SIZE_MAPPINGS.fetch(@size), TRACK_COLOR_MAPPINGS.fetch(@color))
85
+ end
86
+
87
+ def on?
88
+ @checked
89
+ end
90
+
91
+ def disabled?
92
+ @disabled
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,34 @@
1
+ import type { TOutletChangeData } from '../outlet_manager_controller/outlet_manager_controller';
2
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller';
3
+ export interface ToggleableOutlet extends SyncedBooleanAttributesController<boolean> {
4
+ toggle: (event: Event, updateTo?: TOutletChangeData<boolean>) => void;
5
+ }
6
+ export default class ToggleableController extends SyncedBooleanAttributesController<boolean> implements ToggleableOutlet {
7
+ static outlets: string[];
8
+ static values: {
9
+ state: {
10
+ type: BooleanConstructor;
11
+ default: boolean;
12
+ };
13
+ closeOnOutsideClick: {
14
+ type: BooleanConstructor;
15
+ default: boolean;
16
+ };
17
+ syncedAttrs: ArrayConstructor;
18
+ antiAttrs: ArrayConstructor;
19
+ protectAttrs: BooleanConstructor;
20
+ outletEvents: ArrayConstructor;
21
+ };
22
+ stateValue: boolean;
23
+ readonly closeOnOutsideClickValue: boolean;
24
+ connect(): void;
25
+ toggle(event: Event, updateTo?: TOutletChangeData<boolean>): void;
26
+ on(event: Event): void;
27
+ off(event: Event): void;
28
+ clickOutside(event: Event): void;
29
+ getValueForElement(element: Element): boolean | null;
30
+ getElementsToSync(): Element[] | null | undefined;
31
+ getState(): boolean;
32
+ get event_key_postfix(): "on" | "off";
33
+ outletUpdate: (event: Event, updateTo?: TOutletChangeData<boolean>) => void;
34
+ }
@@ -0,0 +1,54 @@
1
+ import { useClickOutside } from 'stimulus-use';
2
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller';
3
+ class ToggleableController extends SyncedBooleanAttributesController {
4
+ constructor() {
5
+ super(...arguments);
6
+ this.outletUpdate = this.toggle;
7
+ }
8
+ connect() {
9
+ this.syncElementAttributes();
10
+ useClickOutside(this, { dispatchEvent: this.closeOnOutsideClickValue && this.stateValue });
11
+ }
12
+ toggle(event, updateTo = {}) {
13
+ var _a;
14
+ const v = (_a = updateTo.data) !== null && _a !== void 0 ? _a : !this.stateValue;
15
+ this.updateAttributesForElement(this.element, v);
16
+ this.stateValue = v;
17
+ this.sendToOutlets(event, Object.assign(Object.assign({}, updateTo), { data: v }));
18
+ }
19
+ on(event) {
20
+ this.toggle(event, { data: true });
21
+ }
22
+ off(event) {
23
+ this.toggle(event, { data: false });
24
+ }
25
+ clickOutside(event) {
26
+ if (this.closeOnOutsideClickValue && this.stateValue) {
27
+ this.toggle(event, { data: false });
28
+ }
29
+ }
30
+ getValueForElement(element) {
31
+ if (element !== this.element) {
32
+ return null;
33
+ }
34
+ return this.stateValue;
35
+ }
36
+ getElementsToSync() {
37
+ return [this.element];
38
+ }
39
+ getState() {
40
+ return this.stateValue;
41
+ }
42
+ get event_key_postfix() {
43
+ return this.stateValue ? 'on' : 'off';
44
+ }
45
+ }
46
+ ToggleableController.outlets = SyncedBooleanAttributesController.outlets;
47
+ ToggleableController.values = Object.assign(Object.assign({}, SyncedBooleanAttributesController.values), { state: {
48
+ type: Boolean,
49
+ default: false,
50
+ }, closeOnOutsideClick: {
51
+ type: Boolean,
52
+ default: false,
53
+ } });
54
+ export default ToggleableController;
@@ -0,0 +1,77 @@
1
+ import type {TOutletChangeData} from '../outlet_manager_controller/outlet_manager_controller'
2
+ import {useClickOutside} from 'stimulus-use'
3
+ import SyncedBooleanAttributesController from '../synced_boolean_attributes_controller/synced_boolean_attributes_controller'
4
+
5
+ export interface ToggleableOutlet extends SyncedBooleanAttributesController<boolean> {
6
+ toggle: (event: Event, updateTo?: TOutletChangeData<boolean>) => void
7
+ }
8
+
9
+ export default class ToggleableController
10
+ extends SyncedBooleanAttributesController<boolean>
11
+ implements ToggleableOutlet
12
+ {
13
+ static outlets = SyncedBooleanAttributesController.outlets
14
+ static values = {
15
+ ...SyncedBooleanAttributesController.values,
16
+ state: {
17
+ type: Boolean,
18
+ default: false,
19
+ },
20
+ closeOnOutsideClick: {
21
+ type: Boolean,
22
+ default: false,
23
+ },
24
+ }
25
+
26
+ declare stateValue: boolean
27
+ declare readonly closeOnOutsideClickValue: boolean
28
+
29
+ connect(): void {
30
+ this.syncElementAttributes()
31
+ useClickOutside(this, {dispatchEvent: this.closeOnOutsideClickValue && this.stateValue})
32
+ }
33
+
34
+ toggle(event: Event, updateTo: TOutletChangeData<boolean> = {}) {
35
+ const v = updateTo.data ?? !this.stateValue
36
+
37
+ this.updateAttributesForElement(this.element, v)
38
+ this.stateValue = v
39
+ this.sendToOutlets(event, {...updateTo, data: v})
40
+ }
41
+
42
+ on(event: Event) {
43
+ this.toggle(event, {data: true})
44
+ }
45
+
46
+ off(event: Event) {
47
+ this.toggle(event, {data: false})
48
+ }
49
+
50
+ clickOutside(event: Event) {
51
+ if (this.closeOnOutsideClickValue && this.stateValue) {
52
+ this.toggle(event, {data: false})
53
+ }
54
+ }
55
+
56
+ getValueForElement(element: Element): boolean | null {
57
+ if (element !== this.element) {
58
+ return null
59
+ }
60
+
61
+ return this.stateValue
62
+ }
63
+
64
+ getElementsToSync(): Element[] | null | undefined {
65
+ return [this.element]
66
+ }
67
+
68
+ getState() {
69
+ return this.stateValue
70
+ }
71
+
72
+ get event_key_postfix() {
73
+ return this.stateValue ? 'on' : 'off'
74
+ }
75
+
76
+ outletUpdate = this.toggle
77
+ }
@@ -3,6 +3,6 @@
3
3
  # :nocov:
4
4
  module Ariadne
5
5
  module ViewComponents
6
- VERSION = "0.0.47"
6
+ VERSION = "0.0.49"
7
7
  end
8
8
  end
data/static/arguments.yml CHANGED
@@ -574,6 +574,21 @@
574
574
  type: Hash
575
575
  default: "`{}`"
576
576
  description: "[Classes and attributes](/classes-attributes)"
577
+ - component: SubheaderComponent
578
+ source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/subheader_component.rb
579
+ parameters:
580
+ - name: tag
581
+ type: Symbol, String
582
+ default: "`:p`"
583
+ description: The rendered tag name.
584
+ - name: classes
585
+ type: String
586
+ default: '`""`'
587
+ description: "[Classes and attributes](/classes-attributes)"
588
+ - name: attributes
589
+ type: Hash
590
+ default: "`{}`"
591
+ description: "[Classes and attributes](/classes-attributes)"
577
592
  - component: TabComponent
578
593
  source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/tab_component.rb
579
594
  parameters:
@@ -702,6 +717,41 @@
702
717
  type: Hash
703
718
  default: "`{}`"
704
719
  description: "[Classes and attributes](/classes-attributes)"
720
+ - component: ToggleComponent
721
+ source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/toggle_component.rb
722
+ parameters:
723
+ - name: classes
724
+ type: String
725
+ default: "`nil`"
726
+ description: "[Classes and attributes](/classes-attributes)"
727
+ - name: color
728
+ type: String
729
+ default: "`:indigo`"
730
+ description: "[Classes and attributes](/classes-attributes)"
731
+ - name: checked
732
+ type: Boolean
733
+ default: "`false`"
734
+ description: "[Classes and attributes](/classes-attributes)"
735
+ - name: disabled
736
+ type: Boolean
737
+ default: "`false`"
738
+ description: "[Classes and attributes](/classes-attributes)"
739
+ - name: size
740
+ type: String
741
+ default: "`:md`"
742
+ description: "[Classes and attributes](/classes-attributes)"
743
+ - name: label
744
+ type: String
745
+ default: N/A
746
+ description: "[Classes and attributes](/classes-attributes)"
747
+ - name: status_label_position
748
+ type: String
749
+ default: "`:start`"
750
+ description: "[Classes and attributes](/classes-attributes)"
751
+ - name: attributes
752
+ type: Hash
753
+ default: "`{}`"
754
+ description: "[Classes and attributes](/classes-attributes)"
705
755
  - component: TooltipComponent
706
756
  source: https://github.com/yettoapp/ariadne/ruby/view_components/tree/main/app/components/ariadne/tooltip_component.rb
707
757
  parameters:
@@ -1,14 +1,22 @@
1
1
  {
2
+ "Ariadne::ActionCardComponent": "",
2
3
  "Ariadne::AvatarComponent": "",
3
4
  "Ariadne::AvatarStackComponent": "",
4
5
  "Ariadne::BaseButton": "",
5
6
  "Ariadne::BaseComponent": "",
6
7
  "Ariadne::BlankslateComponent": "",
7
8
  "Ariadne::BodyComponent": "",
9
+ "Ariadne::BottomTabComponent": "",
10
+ "Ariadne::BottomTabNavComponent": "",
11
+ "Ariadne::BreadcrumbsComponent": "",
8
12
  "Ariadne::ButtonComponent": "",
13
+ "Ariadne::CheckboxComponent": "",
9
14
  "Ariadne::ClipboardCopyComponent": "",
15
+ "Ariadne::CloseButtonComponent": "",
16
+ "Ariadne::ComboboxComponent": "",
10
17
  "Ariadne::CommentComponent": "",
11
18
  "Ariadne::ContainerComponent": "",
19
+ "Ariadne::Content": "",
12
20
  "Ariadne::CounterComponent": "",
13
21
  "Ariadne::DetailsComponent": "",
14
22
  "Ariadne::Dropdown::MenuComponent": "",
@@ -24,15 +32,23 @@
24
32
  "Ariadne::HeroiconComponent": "",
25
33
  "Ariadne::ImageComponent": "",
26
34
  "Ariadne::InlineFlexComponent": "",
35
+ "Ariadne::LayoutComponent": "",
27
36
  "Ariadne::LinkComponent": "",
28
37
  "Ariadne::ListComponent": "",
29
38
  "Ariadne::ListComponent::ListItem": "",
39
+ "Ariadne::ModalComponent": "",
30
40
  "Ariadne::NarrowContainerComponent": "",
31
41
  "Ariadne::PanelBarComponent": "",
32
42
  "Ariadne::PanelBarComponent::PanelItem": "",
33
43
  "Ariadne::PillComponent": "",
44
+ "Ariadne::PopoverComponent": "",
45
+ "Ariadne::ProgressBarComponent": "",
46
+ "Ariadne::RelativeTimeComponent": "",
34
47
  "Ariadne::RichTextAreaComponent": "",
48
+ "Ariadne::ShowMoreButtonComponent": "",
35
49
  "Ariadne::SlideoverComponent": "",
50
+ "Ariadne::SpinnerComponent": "",
51
+ "Ariadne::SubheaderComponent": "",
36
52
  "Ariadne::TabComponent": "",
37
53
  "Ariadne::TabContainerComponent": "",
38
54
  "Ariadne::TabNavComponent": "",
@@ -48,5 +64,6 @@
48
64
  "Ariadne::Text": "",
49
65
  "Ariadne::TimeAgoComponent": "",
50
66
  "Ariadne::TimelineComponent": "",
67
+ "Ariadne::ToggleComponent": "",
51
68
  "Ariadne::TooltipComponent": ""
52
69
  }