@radioactive-labs/plutonium 0.2.1 → 0.3.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.
Files changed (41) hide show
  1. package/package.json +6 -2
  2. package/src/css/plutonium.css +3 -0
  3. package/src/dist/css/plutonium.css +9 -1
  4. package/src/dist/js/plutonium.js +23273 -9599
  5. package/src/dist/js/plutonium.js.map +4 -4
  6. package/src/dist/js/plutonium.min.js +159 -49
  7. package/src/dist/js/plutonium.min.js.map +4 -4
  8. package/src/js/controllers/attachment_input_controller.js +241 -0
  9. package/src/js/controllers/attachment_preview_container_controller.js +15 -0
  10. package/src/js/controllers/attachment_preview_controller.js +63 -0
  11. package/src/js/controllers/color_mode_controller.js +0 -1
  12. package/src/js/controllers/easymde_controller.js +0 -1
  13. package/src/js/controllers/flatpickr_controller.js +0 -1
  14. package/src/js/controllers/form_controller.js +0 -1
  15. package/src/js/controllers/frame_navigator_controller.js +16 -12
  16. package/src/js/controllers/intl_tel_input_controller.js +0 -1
  17. package/src/js/controllers/register_controllers.js +12 -30
  18. package/src/js/controllers/resource_collapse_controller.js +0 -1
  19. package/src/js/controllers/resource_dismiss_controller.js +0 -1
  20. package/src/js/controllers/resource_drop_down_controller.js +161 -9
  21. package/src/js/controllers/{header_controller.js → resource_header_controller.js} +1 -0
  22. package/src/js/controllers/resource_tab_list_controller.js +64 -0
  23. package/src/js/controllers/select_navigator.js +16 -0
  24. package/src/js/controllers/slim_select_controller.js +0 -1
  25. package/src/js/support/dom_element.js +78 -0
  26. package/src/js/support/mime_icon.js +127 -0
  27. package/src/js/controllers/has_many_panel_controller.js +0 -8
  28. package/src/js/controllers/interactive_action_form_controller.js +0 -13
  29. package/src/js/controllers/nav_grid_menu_controller.js +0 -8
  30. package/src/js/controllers/nav_grid_menu_item_controller.js +0 -8
  31. package/src/js/controllers/nav_user_controller.js +0 -8
  32. package/src/js/controllers/nav_user_link_controller.js +0 -8
  33. package/src/js/controllers/nav_user_section_controller.js +0 -8
  34. package/src/js/controllers/resource_layout_controller.js +0 -8
  35. package/src/js/controllers/sidebar_controller.js +0 -8
  36. package/src/js/controllers/sidebar_menu_controller.js +0 -8
  37. package/src/js/controllers/sidebar_menu_item_controller.js +0 -8
  38. package/src/js/controllers/table_controller.js +0 -8
  39. package/src/js/controllers/table_search_input_controller.js +0 -8
  40. package/src/js/controllers/table_toolbar_controller.js +0 -8
  41. package/src/js/controllers/toolbar_controller.js +0 -8
@@ -1,31 +1,183 @@
1
1
  import { Controller } from "@hotwired/stimulus"
2
- import { Dropdown } from 'flowbite';
3
-
2
+ import { createPopper } from '@popperjs/core'
4
3
 
5
4
  // Connects to data-controller="resource-drop-down"
6
5
  export default class extends Controller {
7
6
  static targets = ["trigger", "menu"]
8
7
 
9
8
  connect() {
10
- console.log(`resource-drop-down connected: ${this.element}`)
9
+ this.visible = false
10
+ this.initialized = false
11
+
12
+ // Default options matching Flowbite's defaults
13
+ this.options = {
14
+ placement: 'bottom',
15
+ triggerType: 'click',
16
+ offsetSkidding: 0,
17
+ offsetDistance: 10,
18
+ delay: 300,
19
+ ignoreClickOutsideClass: false
20
+ }
21
+
22
+ this.init()
23
+ }
24
+
25
+ init() {
26
+ if (this.triggerTarget && this.menuTarget && !this.initialized) {
27
+ // Initialize popper instance
28
+ this.popperInstance = createPopper(this.triggerTarget, this.menuTarget, {
29
+ placement: this.options.placement,
30
+ modifiers: [
31
+ {
32
+ name: 'offset',
33
+ options: {
34
+ offset: [this.options.offsetSkidding, this.options.offsetDistance],
35
+ },
36
+ },
37
+ ],
38
+ })
11
39
 
12
- // https://flowbite.com/docs/components/dropdowns/#javascript-behaviour
13
- this.dropdown = new Dropdown(this.menuTarget, this.triggerTarget);
40
+ this.setupEventListeners()
41
+ this.initialized = true
42
+ }
14
43
  }
15
44
 
16
45
  disconnect() {
17
- this.dropdown = null
46
+ if (this.initialized) {
47
+ // Remove click event listeners
48
+ if (this.options.triggerType === 'click') {
49
+ this.triggerTarget.removeEventListener('click', this.clickHandler)
50
+ }
51
+
52
+ // Remove hover event listeners
53
+ if (this.options.triggerType === 'hover') {
54
+ this.triggerTarget.removeEventListener('mouseenter', this.hoverShowTriggerHandler)
55
+ this.menuTarget.removeEventListener('mouseenter', this.hoverShowMenuHandler)
56
+ this.triggerTarget.removeEventListener('mouseleave', this.hoverHideHandler)
57
+ this.menuTarget.removeEventListener('mouseleave', this.hoverHideHandler)
58
+ }
59
+
60
+ // Remove click outside listener
61
+ this.removeClickOutsideListener()
62
+
63
+ // Destroy popper instance
64
+ this.popperInstance.destroy()
65
+ this.initialized = false
66
+ }
67
+ }
68
+
69
+ setupEventListeners() {
70
+ // Bind handlers to preserve context
71
+ this.clickHandler = this.toggle.bind(this)
72
+ this.hoverShowTriggerHandler = (ev) => {
73
+ if (ev.type === 'click') {
74
+ this.toggle()
75
+ } else {
76
+ setTimeout(() => {
77
+ this.show()
78
+ }, this.options.delay)
79
+ }
80
+ }
81
+ this.hoverShowMenuHandler = () => {
82
+ this.show()
83
+ }
84
+ this.hoverHideHandler = () => {
85
+ setTimeout(() => {
86
+ if (!this.menuTarget.matches(':hover')) {
87
+ this.hide()
88
+ }
89
+ }, this.options.delay)
90
+ }
91
+
92
+ // Set up click or hover events based on trigger type
93
+ if (this.options.triggerType === 'click') {
94
+ this.triggerTarget.addEventListener('click', this.clickHandler)
95
+ } else if (this.options.triggerType === 'hover') {
96
+ this.triggerTarget.addEventListener('mouseenter', this.hoverShowTriggerHandler)
97
+ this.menuTarget.addEventListener('mouseenter', this.hoverShowMenuHandler)
98
+ this.triggerTarget.addEventListener('mouseleave', this.hoverHideHandler)
99
+ this.menuTarget.addEventListener('mouseleave', this.hoverHideHandler)
100
+ }
101
+ }
102
+
103
+ setupClickOutsideListener() {
104
+ this.clickOutsideHandler = (ev) => {
105
+ const clickedEl = ev.target
106
+ const ignoreClickOutsideClass = this.options.ignoreClickOutsideClass
107
+
108
+ let isIgnored = false
109
+ if (ignoreClickOutsideClass) {
110
+ const ignoredEls = document.querySelectorAll(`.${ignoreClickOutsideClass}`)
111
+ ignoredEls.forEach((el) => {
112
+ if (el.contains(clickedEl)) {
113
+ isIgnored = true
114
+ return
115
+ }
116
+ })
117
+ }
118
+
119
+ if (
120
+ clickedEl !== this.menuTarget &&
121
+ !this.menuTarget.contains(clickedEl) &&
122
+ !this.triggerTarget.contains(clickedEl) &&
123
+ !isIgnored &&
124
+ this.visible
125
+ ) {
126
+ this.hide()
127
+ }
128
+ }
129
+
130
+ document.body.addEventListener('click', this.clickOutsideHandler, true)
131
+ }
132
+
133
+ removeClickOutsideListener() {
134
+ if (this.clickOutsideHandler) {
135
+ document.body.removeEventListener('click', this.clickOutsideHandler, true)
136
+ }
18
137
  }
19
138
 
20
139
  toggle() {
21
- this.dropdown.toggle()
140
+ if (this.visible) {
141
+ this.hide()
142
+ } else {
143
+ this.show()
144
+ }
22
145
  }
23
146
 
24
147
  show() {
25
- this.dropdown.show()
148
+ this.menuTarget.classList.remove('hidden')
149
+ this.menuTarget.classList.add('block')
150
+ this.menuTarget.removeAttribute('aria-hidden')
151
+
152
+ // Enable popper event listeners
153
+ this.popperInstance.setOptions((options) => ({
154
+ ...options,
155
+ modifiers: [
156
+ ...options.modifiers,
157
+ { name: 'eventListeners', enabled: true },
158
+ ],
159
+ }))
160
+
161
+ this.setupClickOutsideListener()
162
+ this.popperInstance.update()
163
+ this.visible = true
26
164
  }
27
165
 
28
166
  hide() {
29
- this.dropdown.hide()
167
+ this.menuTarget.classList.remove('block')
168
+ this.menuTarget.classList.add('hidden')
169
+ this.menuTarget.setAttribute('aria-hidden', 'true')
170
+
171
+ // Disable popper event listeners
172
+ this.popperInstance.setOptions((options) => ({
173
+ ...options,
174
+ modifiers: [
175
+ ...options.modifiers,
176
+ { name: 'eventListeners', enabled: false },
177
+ ],
178
+ }))
179
+
180
+ this.removeClickOutsideListener()
181
+ this.visible = false
30
182
  }
31
183
  }
@@ -1,5 +1,6 @@
1
1
  import { Controller } from "@hotwired/stimulus"
2
2
 
3
+ // Connects to data-controller="resource-header"
3
4
  export default class extends Controller {
4
5
  static targets = ["openIcon", "closeIcon"]
5
6
  static outlets = ["sidebar"]
@@ -0,0 +1,64 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="resource-tab-list"
4
+ export default class extends Controller {
5
+ static targets = ["btn", "tab"]
6
+ static values = {
7
+ defaultTab: String,
8
+ activeClasses: String,
9
+ inActiveClasses: String
10
+ }
11
+
12
+ connect() {
13
+ this.activeClasses = this.hasActiveClassesValue ? this.activeClassesValue.split(" ") : []
14
+ this.inActiveClasses = this.hasInActiveClassesValue ? this.inActiveClassesValue.split(" ") : []
15
+
16
+ this.#selectInternal(this.defaultTabValue || this.btnTargets[0].id)
17
+ }
18
+
19
+ select(event) {
20
+ this.#selectInternal(event.currentTarget.id)
21
+ }
22
+
23
+ #selectInternal(id) {
24
+ const selectedBtn = this.btnTargets.find(element => element.id === id)
25
+ if (!selectedBtn) {
26
+ console.error(`Tab Button with id "${id}" not found`)
27
+ return
28
+ }
29
+
30
+ const selectedTab = this.tabTargets.find(element => element.id === selectedBtn.dataset.target)
31
+ if (!selectedTab) {
32
+ console.error(`Tab Panel with id "${selectedBtn.dataset.target}" not found`)
33
+ return
34
+ }
35
+
36
+ // Update tab visibility and ARIA states
37
+ this.tabTargets.forEach(tab => {
38
+ tab.hidden = true
39
+ tab.setAttribute('aria-hidden', 'true')
40
+ })
41
+
42
+ // Update button states and classes
43
+ this.btnTargets.forEach(btn => {
44
+ btn.setAttribute('aria-selected', 'false')
45
+ btn.setAttribute('tabindex', '-1')
46
+ btn.classList.remove(...this.activeClasses)
47
+ btn.classList.add(...this.inActiveClasses)
48
+ })
49
+
50
+ // Activate selected tab and button
51
+ selectedBtn.setAttribute('aria-selected', 'true')
52
+ selectedBtn.setAttribute('tabindex', '0')
53
+ selectedBtn.classList.remove(...this.inActiveClasses)
54
+ selectedBtn.classList.add(...this.activeClasses)
55
+
56
+ selectedTab.hidden = false
57
+ selectedTab.setAttribute('aria-hidden', 'false')
58
+
59
+ // Focus management
60
+ if (selectedBtn !== document.activeElement) {
61
+ selectedBtn.focus()
62
+ }
63
+ }
64
+ }
@@ -0,0 +1,16 @@
1
+ import { Controller } from "@hotwired/stimulus"
2
+
3
+ // Connects to data-controller="select-navigator"
4
+ export default class extends Controller {
5
+ static targets = ["select"]
6
+
7
+ navigate(_) {
8
+ const url = this.selectTarget.value
9
+ const anchor = document.createElement('a')
10
+ anchor.href = url
11
+
12
+ this.element.appendChild(anchor)
13
+ anchor.click()
14
+ anchor.remove()
15
+ }
16
+ }
@@ -3,7 +3,6 @@ import { Controller } from "@hotwired/stimulus"
3
3
  // Connects to data-controller="slim-select"
4
4
  export default class extends Controller {
5
5
  connect() {
6
- console.log(`slim-select connected: ${this.element}`)
7
6
  this.slimSelect = new SlimSelect({
8
7
  select: this.element
9
8
  })
@@ -0,0 +1,78 @@
1
+ import DOMPurify from 'dompurify';
2
+
3
+ export default class {
4
+ static fromTemplate(template) {
5
+ if (DOMPurify.isSupported) {
6
+ return DOMPurify.sanitize(template, { USE_PROFILES: { html: true, svg: true }, RETURN_DOM: true }).children[0]
7
+ }
8
+ else {
9
+ const html = new DOMParser().parseFromString(template, 'text/html').body.children[0]
10
+ return santizeHTML(html)
11
+ }
12
+ }
13
+ }
14
+
15
+
16
+ // https://vanillajstoolkit.com/helpers/cleanhtml/
17
+
18
+ /*!
19
+ * Sanitize an HTML node
20
+ */
21
+ function santizeHTML(html) {
22
+ // Sanitize it
23
+ removeScripts(html)
24
+ cleanAttributes(html)
25
+
26
+ return html
27
+ }
28
+
29
+ /**
30
+ * Remove <script> elements
31
+ * @param {Node} html The HTML
32
+ */
33
+ function removeScripts(html) {
34
+ let scripts = html.querySelectorAll('script')
35
+ for (let script of scripts) {
36
+ script.remove()
37
+ }
38
+ }
39
+
40
+ /**
41
+ * Check if the attribute is potentially dangerous
42
+ * @param {String} name The attribute name
43
+ * @param {String} value The attribute value
44
+ * @return {Boolean} If true, the attribute is potentially dangerous
45
+ */
46
+ function isPossiblyDangerous(name, value) {
47
+ let val = value.replace(/\s+/g, '').toLowerCase()
48
+ if (['src', 'href', 'xlink:href'].includes(name)) {
49
+ if (val.includes('javascript:') || val.includes('data:')) return true
50
+ }
51
+ if (name.startsWith('on')) return true
52
+ }
53
+
54
+ /**
55
+ * Remove potentially dangerous attributes from an element
56
+ * @param {Node} elem The element
57
+ */
58
+ function removePossiblyDangerousAttributes(elem) {
59
+ // Loop through each attribute
60
+ // If it's dangerous, remove it
61
+ let atts = elem.attributes
62
+ for (let { name, value } of atts) {
63
+ if (!isPossiblyDangerous(name, value)) continue
64
+ elem.removeAttribute(name)
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Remove dangerous stuff from the HTML document's nodes
70
+ * @param {Node} html The HTML document
71
+ */
72
+ function cleanAttributes(html) {
73
+ let nodes = html.children
74
+ for (let node of nodes) {
75
+ removePossiblyDangerousAttributes(node)
76
+ cleanAttributes(node)
77
+ }
78
+ }
@@ -0,0 +1,127 @@
1
+ import DomElement from "./dom_element"
2
+
3
+ function iconImage() {
4
+ return DomElement.fromTemplate(`
5
+ <svg aria-hidden="true" focusable="false" width="25" height="25" viewBox="0 0 25 25">
6
+ <g fill="#686DE0" fillRule="evenodd">
7
+ <path d="M5 7v10h15V7H5zm0-1h15a1 1 0 0 1 1 1v10a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V7a1 1 0 0 1 1-1z" fillRule="nonzero" />
8
+ <path d="M6.35 17.172l4.994-5.026a.5.5 0 0 1 .707 0l2.16 2.16 3.505-3.505a.5.5 0 0 1 .707 0l2.336 2.31-.707.72-1.983-1.97-3.505 3.505a.5.5 0 0 1-.707 0l-2.16-2.159-3.938 3.939-1.409.026z" fillRule="nonzero" />
9
+ <circle cx="7.5" cy="9.5" r="1.5" />
10
+ </g>
11
+ </svg>
12
+ `)
13
+ }
14
+
15
+ function iconAudio() {
16
+ return DomElement.fromTemplate(`
17
+ <svg aria-hidden="true" focusable="false" className="uppy-c-icon" width="25" height="25" viewBox="0 0 25 25">
18
+ <path d="M9.5 18.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V7.25a.5.5 0 0 1 .379-.485l9-2.25A.5.5 0 0 1 18.5 5v11.64c0 1.14-1.145 2-2.5 2s-2.5-.86-2.5-2c0-1.14 1.145-2 2.5-2 .557 0 1.079.145 1.5.396V8.67l-8 2v7.97zm8-11v-2l-8 2v2l8-2zM7 19.64c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1zm9-2c.855 0 1.5-.484 1.5-1s-.645-1-1.5-1-1.5.484-1.5 1 .645 1 1.5 1z" fill="#049BCF" fillRule="nonzero" />
19
+ </svg>
20
+ `)
21
+ }
22
+
23
+ function iconVideo() {
24
+ return DomElement.fromTemplate(`
25
+ <svg aria-hidden="true" focusable="false" className="uppy-c-icon" width="25" height="25" viewBox="0 0 25 25">
26
+ <path d="M16 11.834l4.486-2.691A1 1 0 0 1 22 10v6a1 1 0 0 1-1.514.857L16 14.167V17a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1h10a1 1 0 0 1 1 1v2.834zM15 9H5v8h10V9zm1 4l5 3v-6l-5 3z" fill="#19AF67" fillRule="nonzero" />
27
+ </svg>
28
+ `)
29
+ }
30
+
31
+ function iconPDF() {
32
+ return DomElement.fromTemplate(`
33
+ <svg aria-hidden="true" focusable="false" className="uppy-c-icon" width="25" height="25" viewBox="0 0 25 25">
34
+ <path d="M9.766 8.295c-.691-1.843-.539-3.401.747-3.726 1.643-.414 2.505.938 2.39 3.299-.039.79-.194 1.662-.537 3.148.324.49.66.967 1.055 1.51.17.231.382.488.629.757 1.866-.128 3.653.114 4.918.655 1.487.635 2.192 1.685 1.614 2.84-.566 1.133-1.839 1.084-3.416.249-1.141-.604-2.457-1.634-3.51-2.707a13.467 13.467 0 0 0-2.238.426c-1.392 4.051-4.534 6.453-5.707 4.572-.986-1.58 1.38-4.206 4.914-5.375.097-.322.185-.656.264-1.001.08-.353.306-1.31.407-1.737-.678-1.059-1.2-2.031-1.53-2.91zm2.098 4.87c-.033.144-.068.287-.104.427l.033-.01-.012.038a14.065 14.065 0 0 1 1.02-.197l-.032-.033.052-.004a7.902 7.902 0 0 1-.208-.271c-.197-.27-.38-.526-.555-.775l-.006.028-.002-.003c-.076.323-.148.632-.186.8zm5.77 2.978c1.143.605 1.832.632 2.054.187.26-.519-.087-1.034-1.113-1.473-.911-.39-2.175-.608-3.55-.608.845.766 1.787 1.459 2.609 1.894zM6.559 18.789c.14.223.693.16 1.425-.413.827-.648 1.61-1.747 2.208-3.206-2.563 1.064-4.102 2.867-3.633 3.62zm5.345-10.97c.088-1.793-.351-2.48-1.146-2.28-.473.119-.564 1.05-.056 2.405.213.566.52 1.188.908 1.859.18-.858.268-1.453.294-1.984z" fill="#E2514A" fillRule="nonzero" />
35
+ </svg>
36
+ `)
37
+ }
38
+
39
+ function iconArchive() {
40
+ return DomElement.fromTemplate(`
41
+ <svg aria-hidden="true" focusable="false" width="25" height="25" viewBox="0 0 25 25">
42
+ <path d="M10.45 2.05h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5V2.55a.5.5 0 0 1 .5-.5zm2.05 1.024h1.05a.5.5 0 0 1 .5.5V3.6a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5v-.001zM10.45 0h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5V.5a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.024a.5.5 0 0 1 .5-.5zm-2.05 3.074h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.024a.5.5 0 0 1 .5-.5zm-2.05 1.024h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm-2.05 1.025h1.05a.5.5 0 0 1 .5.5v.025a.5.5 0 0 1-.5.5h-1.05a.5.5 0 0 1-.5-.5v-.025a.5.5 0 0 1 .5-.5zm2.05 1.025h1.05a.5.5 0 0 1 .5.5v.024a.5.5 0 0 1-.5.5H12.5a.5.5 0 0 1-.5-.5v-.024a.5.5 0 0 1 .5-.5zm-1.656 3.074l-.82 5.946c.52.302 1.174.458 1.976.458.803 0 1.455-.156 1.975-.458l-.82-5.946h-2.311zm0-1.025h2.312c.512 0 .946.378 1.015.885l.82 5.946c.056.412-.142.817-.501 1.026-.686.398-1.515.597-2.49.597-.974 0-1.804-.199-2.49-.597a1.025 1.025 0 0 1-.5-1.026l.819-5.946c.07-.507.503-.885 1.015-.885zm.545 6.6a.5.5 0 0 1-.397-.561l.143-.999a.5.5 0 0 1 .495-.429h.74a.5.5 0 0 1 .495.43l.143.998a.5.5 0 0 1-.397.561c-.404.08-.819.08-1.222 0z" fill="#00C469" fillRule="nonzero" />
43
+ </svg>
44
+ `)
45
+ }
46
+
47
+ function iconFile() {
48
+ return DomElement.fromTemplate(`
49
+ <svg aria-hidden="true" focusable="false" className="uppy-c-icon" width="25" height="25" viewBox="0 0 25 25">
50
+ <g fill="#A7AFB7" fillRule="nonzero">
51
+ <path d="M5.5 22a.5.5 0 0 1-.5-.5v-18a.5.5 0 0 1 .5-.5h10.719a.5.5 0 0 1 .367.16l3.281 3.556a.5.5 0 0 1 .133.339V21.5a.5.5 0 0 1-.5.5h-14zm.5-1h13V7.25L16 4H6v17z" />
52
+ <path d="M15 4v3a1 1 0 0 0 1 1h3V7h-3V4h-1z" />
53
+ </g>
54
+ </svg>
55
+ `)
56
+ }
57
+
58
+ function iconText() {
59
+ return DomElement.fromTemplate(`
60
+ <svg aria-hidden="true" focusable="false" className="uppy-c-icon" width="25" height="25" viewBox="0 0 25 25">
61
+ <path d="M4.5 7h13a.5.5 0 1 1 0 1h-13a.5.5 0 0 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h15a.5.5 0 1 1 0 1h-15a.5.5 0 1 1 0-1zm0 3h10a.5.5 0 1 1 0 1h-10a.5.5 0 1 1 0-1z" fill="#5A5E69" fillRule="nonzero" />
62
+ </svg>
63
+ `)
64
+ }
65
+
66
+ export default function getIconByMime(fileType) {
67
+ const defaultChoice = {
68
+ color: '#838999',
69
+ icon: iconFile(),
70
+ }
71
+
72
+ if (!fileType) return defaultChoice
73
+
74
+ const fileTypeGeneral = fileType.split('/')[0]
75
+ const fileTypeSpecific = fileType.split('/')[1]
76
+
77
+ // Text
78
+ if (fileTypeGeneral === 'text') {
79
+ return {
80
+ color: '#5a5e69',
81
+ icon: iconText(),
82
+ }
83
+ }
84
+
85
+ // Image
86
+ if (fileTypeGeneral === 'image') {
87
+ return {
88
+ color: '#686de0',
89
+ icon: iconImage(),
90
+ }
91
+ }
92
+
93
+ // Audio
94
+ if (fileTypeGeneral === 'audio') {
95
+ return {
96
+ color: '#068dbb',
97
+ icon: iconAudio(),
98
+ }
99
+ }
100
+
101
+ // Video
102
+ if (fileTypeGeneral === 'video') {
103
+ return {
104
+ color: '#19af67',
105
+ icon: iconVideo(),
106
+ }
107
+ }
108
+
109
+ // PDF
110
+ if (fileTypeGeneral === 'application' && fileTypeSpecific === 'pdf') {
111
+ return {
112
+ color: '#e25149',
113
+ icon: iconPDF(),
114
+ }
115
+ }
116
+
117
+ // Archive
118
+ const archiveTypes = ['zip', 'x-7z-compressed', 'x-rar-compressed', 'x-tar', 'x-gzip', 'x-apple-diskimage']
119
+ if (fileTypeGeneral === 'application' && archiveTypes.indexOf(fileTypeSpecific) !== -1) {
120
+ return {
121
+ color: '#00C469',
122
+ icon: iconArchive(),
123
+ }
124
+ }
125
+
126
+ return defaultChoice
127
+ }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="has-many-panel"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`has-many-panel connected: ${this.element}`)
7
- }
8
- }
@@ -1,13 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
- import debounce from "lodash.debounce";
3
-
4
- // Connects to data-controller="interactive-action-form"
5
- export default class extends Controller {
6
- connect() {
7
- console.log(`interactive-action-form connected: ${this.element}`)
8
- }
9
-
10
- submit() {
11
- this.element.requestSubmit()
12
- }
13
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="nav-grid-menu"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`nav-grid-menu connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="nav-grid-menu-item"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`nav-grid-menu-item connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="nav-user"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`nav-user connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="nav-user-link"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`nav-user-link connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="nav-user-section"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`nav-user-section connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="resource-layout"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`resource-layout connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="sidebar"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`sidebar connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="sidebar-menu"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`sidebar-menu connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="sidebar-menu-item"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`sidebar-menu-item connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="table"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`table connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="table-search-input"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`table-search-input connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="table-toolbar"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`table-toolbar connected: ${this.element}`)
7
- }
8
- }
@@ -1,8 +0,0 @@
1
- import { Controller } from "@hotwired/stimulus"
2
-
3
- // Connects to data-controller="toolbar"
4
- export default class extends Controller {
5
- connect() {
6
- console.log(`toolbar connected: ${this.element}`)
7
- }
8
- }