polaris_view_components 0.6.0 → 0.7.0
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.
- checksums.yaml +4 -4
- data/README.md +12 -2
- data/app/assets/javascripts/polaris_view_components/autocomplete_controller.js +119 -0
- data/app/assets/javascripts/polaris_view_components/button_controller.js +4 -5
- data/app/assets/javascripts/polaris_view_components/frame_controller.js +41 -0
- data/app/assets/javascripts/polaris_view_components/index.js +9 -1
- data/app/assets/javascripts/polaris_view_components/option_list_controller.js +41 -0
- data/app/assets/javascripts/polaris_view_components/polaris_controller.js +4 -0
- data/app/assets/javascripts/polaris_view_components/popover_controller.js +6 -2
- data/app/assets/javascripts/polaris_view_components/text_field_controller.js +4 -0
- data/app/assets/javascripts/polaris_view_components/toast_controller.js +68 -0
- data/app/assets/javascripts/polaris_view_components.js +415 -18
- data/app/assets/stylesheets/polaris_view_components/custom.css +41 -0
- data/app/assets/stylesheets/polaris_view_components.css +25 -0
- data/app/components/polaris/autocomplete/action_component.rb +7 -0
- data/app/components/polaris/autocomplete/option_component.rb +35 -0
- data/app/components/polaris/autocomplete/section_component.html.erb +9 -0
- data/app/components/polaris/autocomplete/section_component.rb +12 -0
- data/app/components/polaris/autocomplete_component.html.erb +30 -0
- data/app/components/polaris/autocomplete_component.rb +58 -0
- data/app/components/polaris/base_checkbox.rb +48 -0
- data/app/components/polaris/base_radio_button.rb +38 -0
- data/app/components/polaris/checkbox_component.html.erb +1 -5
- data/app/components/polaris/checkbox_component.rb +15 -8
- data/app/components/polaris/choice_list_component.rb +1 -1
- data/app/components/polaris/filters_component.html.erb +22 -0
- data/app/components/polaris/filters_component.rb +57 -4
- data/app/components/polaris/frame/save_bar_component.html.erb +23 -0
- data/app/components/polaris/frame/save_bar_component.rb +31 -0
- data/app/components/polaris/frame/top_bar_component.html.erb +30 -0
- data/app/components/polaris/frame/top_bar_component.rb +18 -0
- data/app/components/polaris/frame_component.html.erb +44 -0
- data/app/components/polaris/frame_component.rb +33 -0
- data/app/components/polaris/logo.rb +13 -0
- data/app/components/polaris/navigation/item_component.html.erb +31 -0
- data/app/components/polaris/navigation/item_component.rb +85 -0
- data/app/components/polaris/navigation/section_component.html.erb +17 -0
- data/app/components/polaris/navigation/section_component.rb +64 -0
- data/app/components/polaris/navigation_component.html.erb +29 -0
- data/app/components/polaris/navigation_component.rb +15 -0
- data/app/components/polaris/option_list/checkbox_component.html.erb +14 -0
- data/app/components/polaris/option_list/checkbox_component.rb +37 -0
- data/app/components/polaris/option_list/option_component.rb +24 -0
- data/app/components/polaris/option_list/radio_button_component.rb +54 -0
- data/app/components/polaris/option_list/section_component.html.erb +14 -0
- data/app/components/polaris/option_list/section_component.rb +53 -0
- data/app/components/polaris/option_list_component.html.erb +15 -0
- data/app/components/polaris/option_list_component.rb +67 -0
- data/app/components/polaris/popover_component.html.erb +2 -9
- data/app/components/polaris/popover_component.rb +17 -0
- data/app/components/polaris/radio_button_component.html.erb +1 -6
- data/app/components/polaris/radio_button_component.rb +14 -4
- data/app/components/polaris/text_field_component.rb +16 -2
- data/app/components/polaris/toast_component.html.erb +21 -0
- data/app/components/polaris/toast_component.rb +40 -0
- data/app/components/polaris/top_bar/user_menu_component.html.erb +19 -0
- data/app/components/polaris/top_bar/user_menu_component.rb +9 -0
- data/app/helpers/polaris/form_builder.rb +2 -2
- data/app/helpers/polaris/view_helper.rb +11 -0
- data/lib/polaris/view_components/engine.rb +5 -1
- data/lib/polaris/view_components/version.rb +1 -1
- metadata +46 -9
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b9e5671bf20a8c0aec20920be9fcea01ba39b902057eec479f30b9d621bdbf50
|
4
|
+
data.tar.gz: 21bb979fd293cd8379e0e012e9ef2ee9ae06cf62bfdd226fc1ae90ff3b65e9c3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 638f5ef1f9c7be3d41b1f1b9016f3a8f14f13c3fbc65c5df6ab8f02b7e903f7456a01514f1d5297c3ecbc022bf66d4283a014a602a9a49662b9d99a368d1a88a
|
7
|
+
data.tar.gz: f482994119dd2a2334bf633eae54cb8998d39d38821efc9d16bd88af92869f7f9e18f418cc1f71e2fdf7bbb0d6558cd449c24ae61f93dd660950104b192f4427
|
data/README.md
CHANGED
@@ -8,7 +8,7 @@ Polaris ViewComponents is an implementation of the Polaris Design System using [
|
|
8
8
|
|
9
9
|
## Preview
|
10
10
|
|
11
|
-
https://
|
11
|
+
https://polarisviewcomponents.org
|
12
12
|
|
13
13
|
## Usage
|
14
14
|
|
@@ -47,6 +47,16 @@ Define Polaris style on your `<body>` tag:
|
|
47
47
|
|
48
48
|
### Importmaps
|
49
49
|
|
50
|
+
Install dependencies:
|
51
|
+
```
|
52
|
+
bin/importmap pin @rails/request.js --download
|
53
|
+
```
|
54
|
+
|
55
|
+
If you use sprockets make sure the vendor folder is loaded in `app/assets/config/manifest.js`:
|
56
|
+
```js
|
57
|
+
//= link_tree ../../../vendor/assets/javascripts .js
|
58
|
+
```
|
59
|
+
|
50
60
|
Add to `config/importmap.rb`:
|
51
61
|
|
52
62
|
```rb
|
@@ -65,7 +75,7 @@ registerPolarisControllers(Stimulus)
|
|
65
75
|
|
66
76
|
Install NPM package:
|
67
77
|
```bash
|
68
|
-
yarn add polaris-view-components
|
78
|
+
yarn add polaris-view-components @rails/request.js
|
69
79
|
```
|
70
80
|
|
71
81
|
Add to `app/javascript/controllers/index.js`:
|
@@ -0,0 +1,119 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
2
|
+
import { get } from '@rails/request.js'
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static targets = ['popover', 'input', 'results', 'option', 'emptyState']
|
6
|
+
static values = { url: String }
|
7
|
+
|
8
|
+
connect() {
|
9
|
+
this.inputTarget.addEventListener("input", this.onInputChange)
|
10
|
+
}
|
11
|
+
|
12
|
+
disconnect() {
|
13
|
+
this.inputTarget.removeEventListener("input", this.onInputChange)
|
14
|
+
}
|
15
|
+
|
16
|
+
// Actions
|
17
|
+
|
18
|
+
toggle() {
|
19
|
+
if (this.visibleOptions.length > 0) {
|
20
|
+
this.hideEmptyState()
|
21
|
+
this.popoverController.show()
|
22
|
+
} else if (this.value.length > 0 && this.hasEmptyStateTarget) {
|
23
|
+
this.showEmptyState()
|
24
|
+
} else {
|
25
|
+
this.popoverController.forceHide()
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
select(event) {
|
30
|
+
const input = event.currentTarget
|
31
|
+
const label = input.closest('li').dataset.label
|
32
|
+
const changeEvent = new CustomEvent('polaris-autocomplete:change', {
|
33
|
+
detail: { value: input.value, label, selected: input.checked }
|
34
|
+
})
|
35
|
+
|
36
|
+
this.element.dispatchEvent(changeEvent)
|
37
|
+
}
|
38
|
+
|
39
|
+
onInputChange = debounce(() => {
|
40
|
+
if (this.isRemote) {
|
41
|
+
this.fetchResults()
|
42
|
+
} else {
|
43
|
+
this.filterOptions()
|
44
|
+
}
|
45
|
+
}, 200)
|
46
|
+
|
47
|
+
|
48
|
+
// Private
|
49
|
+
|
50
|
+
get isRemote() {
|
51
|
+
return this.urlValue.length > 0
|
52
|
+
}
|
53
|
+
|
54
|
+
get popoverController() {
|
55
|
+
return this.application.getControllerForElementAndIdentifier(this.popoverTarget, 'polaris-popover')
|
56
|
+
}
|
57
|
+
|
58
|
+
get value() {
|
59
|
+
return this.inputTarget.value
|
60
|
+
}
|
61
|
+
|
62
|
+
get visibleOptions() {
|
63
|
+
return this.optionTargets.filter(option => {
|
64
|
+
return !option.classList.contains('Polaris--hidden')
|
65
|
+
})
|
66
|
+
}
|
67
|
+
|
68
|
+
filterOptions() {
|
69
|
+
if (this.value === '') {
|
70
|
+
this.optionTargets.forEach(option => {
|
71
|
+
option.classList.remove('Polaris--hidden')
|
72
|
+
})
|
73
|
+
} else {
|
74
|
+
const filterRegex = new RegExp(this.value, 'i')
|
75
|
+
this.optionTargets.forEach(option => {
|
76
|
+
if (option.dataset.label.match(filterRegex)) {
|
77
|
+
option.classList.remove('Polaris--hidden')
|
78
|
+
} else {
|
79
|
+
option.classList.add('Polaris--hidden')
|
80
|
+
}
|
81
|
+
})
|
82
|
+
}
|
83
|
+
this.toggle()
|
84
|
+
}
|
85
|
+
|
86
|
+
async fetchResults() {
|
87
|
+
const response = await get(this.urlValue, {
|
88
|
+
query: { q: this.value }
|
89
|
+
})
|
90
|
+
if (response.ok) {
|
91
|
+
const results = await response.html
|
92
|
+
this.resultsTarget.innerHTML = results
|
93
|
+
this.toggle()
|
94
|
+
}
|
95
|
+
}
|
96
|
+
|
97
|
+
showEmptyState() {
|
98
|
+
if (this.hasEmptyStateTarget) {
|
99
|
+
this.resultsTarget.classList.add('Polaris--hidden')
|
100
|
+
this.emptyStateTarget.classList.remove('Polaris--hidden')
|
101
|
+
}
|
102
|
+
}
|
103
|
+
|
104
|
+
hideEmptyState() {
|
105
|
+
if (this.hasEmptyStateTarget) {
|
106
|
+
this.emptyStateTarget.classList.add('Polaris--hidden')
|
107
|
+
this.resultsTarget.classList.remove('Polaris--hidden')
|
108
|
+
}
|
109
|
+
}
|
110
|
+
}
|
111
|
+
|
112
|
+
const debounce = (fn, delay = 10) => {
|
113
|
+
let timeoutId = null
|
114
|
+
|
115
|
+
return (...args) => {
|
116
|
+
clearTimeout(timeoutId)
|
117
|
+
timeoutId = setTimeout(fn, delay)
|
118
|
+
}
|
119
|
+
}
|
@@ -2,21 +2,20 @@ import { Controller } from "@hotwired/stimulus"
|
|
2
2
|
|
3
3
|
export default class extends Controller {
|
4
4
|
disable(event) {
|
5
|
-
if (this.button.
|
5
|
+
if (this.button.disabled) {
|
6
6
|
event.preventDefault()
|
7
7
|
} else {
|
8
|
-
this.button.
|
8
|
+
this.button.disabled = true
|
9
9
|
this.button.classList.add("Polaris-Button--disabled", "Polaris-Button--loading")
|
10
10
|
this.buttonContent.insertAdjacentHTML("afterbegin", this.spinnerHTML)
|
11
11
|
}
|
12
12
|
}
|
13
13
|
|
14
14
|
enable() {
|
15
|
-
if (this.button.
|
15
|
+
if (this.button.disabled) {
|
16
16
|
this.button.disabled = false
|
17
|
-
delete this.button.dataset.disabled
|
18
17
|
this.button.classList.remove("Polaris-Button--disabled", "Polaris-Button--loading")
|
19
|
-
this.spinner.remove()
|
18
|
+
if (this.spinner) this.spinner.remove()
|
20
19
|
}
|
21
20
|
}
|
22
21
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
import { useTransition } from "stimulus-use"
|
3
|
+
|
4
|
+
export default class extends Controller {
|
5
|
+
static targets = ["navigationOverlay", "navigation", "saveBar"]
|
6
|
+
|
7
|
+
connect() {
|
8
|
+
if (!this.hasNavigationTarget) { return }
|
9
|
+
|
10
|
+
useTransition(this, {
|
11
|
+
element: this.navigationTarget,
|
12
|
+
enterFrom: "Polaris-Frame__Navigation--enter",
|
13
|
+
enterTo: "Polaris-Frame__Navigation--visible Polaris-Frame__Navigation--enterActive",
|
14
|
+
leaveActive: "Polaris-Frame__Navigation--exitActive",
|
15
|
+
leaveFrom: "Polaris-Frame__Navigation--exit",
|
16
|
+
leaveTo: "",
|
17
|
+
removeToClasses: false,
|
18
|
+
hiddenClass: false,
|
19
|
+
})
|
20
|
+
}
|
21
|
+
|
22
|
+
// Actions
|
23
|
+
|
24
|
+
openMenu() {
|
25
|
+
this.enter()
|
26
|
+
this.navigationOverlayTarget.classList.add("Polaris-Backdrop", "Polaris-Backdrop--belowNavigation")
|
27
|
+
}
|
28
|
+
|
29
|
+
closeMenu() {
|
30
|
+
this.leave()
|
31
|
+
this.navigationOverlayTarget.classList.remove("Polaris-Backdrop", "Polaris-Backdrop--belowNavigation")
|
32
|
+
}
|
33
|
+
|
34
|
+
showSaveBar() {
|
35
|
+
this.saveBarTarget.classList.add("Polaris-Frame-CSSAnimation--endFade")
|
36
|
+
}
|
37
|
+
|
38
|
+
hideSaveBar() {
|
39
|
+
this.saveBarTarget.classList.remove("Polaris-Frame-CSSAnimation--endFade")
|
40
|
+
}
|
41
|
+
}
|
@@ -1,21 +1,29 @@
|
|
1
|
+
import Autocomplete from './autocomplete_controller'
|
1
2
|
import Button from './button_controller'
|
3
|
+
import Frame from './frame_controller'
|
2
4
|
import Modal from './modal_controller'
|
5
|
+
import OptionList from './option_list_controller'
|
3
6
|
import Polaris from './polaris_controller'
|
4
7
|
import Popover from './popover_controller'
|
5
8
|
import ResourceItem from './resource_item_controller'
|
6
9
|
import Scrollable from './scrollable_controller'
|
7
10
|
import Select from './select_controller'
|
8
11
|
import TextField from './text_field_controller'
|
12
|
+
import Toast from './toast_controller'
|
9
13
|
|
10
|
-
export { Modal, Polaris, Popover, ResourceItem, Scrollable, Select, TextField }
|
14
|
+
export { Frame, Modal, Polaris, Popover, ResourceItem, Scrollable, Select, TextField }
|
11
15
|
|
12
16
|
export function registerPolarisControllers(application) {
|
17
|
+
application.register('polaris-autocomplete', Autocomplete)
|
13
18
|
application.register('polaris-button', Button)
|
19
|
+
application.register('polaris-frame', Frame)
|
14
20
|
application.register('polaris-modal', Modal)
|
21
|
+
application.register('polaris-option-list', OptionList)
|
15
22
|
application.register('polaris', Polaris)
|
16
23
|
application.register('polaris-popover', Popover)
|
17
24
|
application.register('polaris-resource-item', ResourceItem)
|
18
25
|
application.register('polaris-scrollable', Scrollable)
|
19
26
|
application.register('polaris-select', Select)
|
20
27
|
application.register('polaris-text-field', TextField)
|
28
|
+
application.register('polaris-toast', Toast)
|
21
29
|
}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
import { Controller } from "@hotwired/stimulus"
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static targets = ["radioButton"]
|
5
|
+
static classes = ["selected"]
|
6
|
+
|
7
|
+
connect() {
|
8
|
+
this.updateSelected()
|
9
|
+
}
|
10
|
+
|
11
|
+
// Actions
|
12
|
+
|
13
|
+
update(event) {
|
14
|
+
const target = event.currentTarget
|
15
|
+
target.classList.add(this.selectedClass)
|
16
|
+
this.deselectAll(target)
|
17
|
+
}
|
18
|
+
|
19
|
+
// Private
|
20
|
+
|
21
|
+
updateSelected() {
|
22
|
+
this.radioButtonTargets.forEach(element => {
|
23
|
+
const input = element.querySelector('input[type=radio]')
|
24
|
+
if (input.checked) {
|
25
|
+
element.classList.add(this.selectedClass)
|
26
|
+
} else {
|
27
|
+
element.classList.remove(this.selectedClass)
|
28
|
+
}
|
29
|
+
})
|
30
|
+
}
|
31
|
+
|
32
|
+
deselectAll(target) {
|
33
|
+
this.radioButtonTargets.forEach(element => {
|
34
|
+
if (!element.isEqualNode(target)) {
|
35
|
+
const input = element.querySelector('input[type=radio]')
|
36
|
+
input.checked = false
|
37
|
+
element.classList.remove(this.selectedClass)
|
38
|
+
}
|
39
|
+
})
|
40
|
+
}
|
41
|
+
}
|
@@ -38,8 +38,12 @@ export default class extends Controller {
|
|
38
38
|
|
39
39
|
hide(event) {
|
40
40
|
if (!this.element.contains(event.target) && !this.popoverTarget.classList.contains(this.closedClass)) {
|
41
|
-
this.
|
42
|
-
this.popoverTarget.classList.add(this.closedClass)
|
41
|
+
this.forceHide()
|
43
42
|
}
|
44
43
|
}
|
44
|
+
|
45
|
+
forceHide() {
|
46
|
+
this.popoverTarget.classList.remove(this.openClass)
|
47
|
+
this.popoverTarget.classList.add(this.closedClass)
|
48
|
+
}
|
45
49
|
}
|
@@ -101,11 +101,15 @@ export default class extends Controller {
|
|
101
101
|
// step / value has.
|
102
102
|
const decimalPlaces = Math.max(dpl(numericValue), dpl(this.stepValue))
|
103
103
|
|
104
|
+
const oldValue = this.value
|
104
105
|
const newValue = Math.min(
|
105
106
|
Number(this.maxValue),
|
106
107
|
Math.max(numericValue + steps * this.stepValue, Number(this.minValue)),
|
107
108
|
)
|
108
109
|
|
109
110
|
this.value = String(newValue.toFixed(decimalPlaces))
|
111
|
+
if (this.value != oldValue) {
|
112
|
+
this.inputTarget.dispatchEvent(new Event('change'))
|
113
|
+
}
|
110
114
|
}
|
111
115
|
}
|
@@ -0,0 +1,68 @@
|
|
1
|
+
import { Controller } from '@hotwired/stimulus'
|
2
|
+
|
3
|
+
export default class extends Controller {
|
4
|
+
static activeClass = 'Polaris-Frame-ToastManager--toastWrapperEnterDone'
|
5
|
+
static defaultDuration = 5000
|
6
|
+
static defaultDurationWithAction = 10000
|
7
|
+
static values = { hidden: Boolean, duration: Number, hasAction: Boolean }
|
8
|
+
|
9
|
+
connect() {
|
10
|
+
if (!this.hiddenValue) {
|
11
|
+
this.show()
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
show = () => {
|
16
|
+
this.element.dataset.position = this.position
|
17
|
+
this.element.style.cssText = this.getStyle(this.position)
|
18
|
+
this.element.classList.add(this.constructor.activeClass)
|
19
|
+
setTimeout(this.close, this.timeoutDuration)
|
20
|
+
}
|
21
|
+
|
22
|
+
close = () => {
|
23
|
+
this.element.classList.remove(this.constructor.activeClass)
|
24
|
+
this.element.addEventListener('transitionend', this.updatePositions, false)
|
25
|
+
}
|
26
|
+
|
27
|
+
updatePositions = () => {
|
28
|
+
this.visibleToasts
|
29
|
+
.sort((a, b) => parseInt(a.dataset.position) - parseInt(b.dataset.position))
|
30
|
+
.forEach((toast, index) => {
|
31
|
+
const position = index + 1
|
32
|
+
toast.dataset.position = position
|
33
|
+
toast.style.cssText = this.getStyle(position)
|
34
|
+
})
|
35
|
+
|
36
|
+
this.element.removeEventListener('transitionend', this.updatePositions, false)
|
37
|
+
}
|
38
|
+
|
39
|
+
getStyle(position) {
|
40
|
+
const translateIn = -80 * position
|
41
|
+
const translateOut = 150 - (80 * position)
|
42
|
+
return `--toast-translate-y-in: ${translateIn}px; --toast-translate-y-out: ${translateOut}px;`
|
43
|
+
}
|
44
|
+
|
45
|
+
get timeoutDuration() {
|
46
|
+
if (this.durationValue > 0) {
|
47
|
+
return this.durationValue
|
48
|
+
} else if (this.hasActionValue) {
|
49
|
+
return this.constructor.defaultDurationWithAction
|
50
|
+
} else {
|
51
|
+
return this.constructor.defaultDuration
|
52
|
+
}
|
53
|
+
}
|
54
|
+
|
55
|
+
get toastManager() {
|
56
|
+
return this.element.closest('.Polaris-Frame-ToastManager')
|
57
|
+
}
|
58
|
+
|
59
|
+
get visibleToasts() {
|
60
|
+
return [
|
61
|
+
...this.toastManager.querySelectorAll(`.${this.constructor.activeClass}`)
|
62
|
+
]
|
63
|
+
}
|
64
|
+
|
65
|
+
get position() {
|
66
|
+
return this.visibleToasts.filter(el => !this.element.isEqualNode(el)).length + 1
|
67
|
+
}
|
68
|
+
}
|