mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-07-24 18:09:13 -04:00
Removed jquery from a few simple javascript files
This commit is contained in:
@@ -1,94 +1,70 @@
|
||||
(function(window) {
|
||||
"use strict";
|
||||
|
||||
if (!document.queryCommandSupported('copy')) return;
|
||||
// Only initialize if modern Clipboard API is available
|
||||
if (!navigator.clipboard) return;
|
||||
|
||||
window.NotifyModules['copy-to-clipboard'] = function() {
|
||||
|
||||
const states = {
|
||||
'valueVisible': (options) => `
|
||||
<span class="copy-to-clipboard__value margin-bottom-1">${options.valueLabel ? '<span class="usa-sr-only">' + options.thing + ': </span>' : ''}${options.value}</span>
|
||||
<span class="copy-to-clipboard__notice" aria-live="assertive">
|
||||
${options.onload ? '' : options.thing + ' returned to page, press button to copy to clipboard'}
|
||||
</span>
|
||||
<button class="usa-button usa-button--outline copy-to-clipboard__button--copy">
|
||||
Copy ${options.thing} to clipboard${options.name ? '<span class="usa-sr-only"> for ' + options.name + '</span>' : ''}
|
||||
</button>
|
||||
`,
|
||||
'valueCopied': (options) => `
|
||||
<span class="copy-to-clipboard__notice" aria-live="assertive">
|
||||
<span class="usa-sr-only">${options.thing} </span>Copied to clipboard<span class="usa-sr-only">, press button to show in page</span>
|
||||
</span>
|
||||
<button class="usa-button copy-to-clipboard__button--show">
|
||||
Show ${options.thing}${options.name ? '<span class="usa-sr-only"> for ' + options.name + '</span>' : ''}
|
||||
</button>
|
||||
`
|
||||
};
|
||||
|
||||
this.getRangeFromElement = function (copyableElement) {
|
||||
const range = document.createRange();
|
||||
const childNodes = Array.prototype.slice.call(copyableElement.childNodes);
|
||||
let prefixIndex = -1;
|
||||
|
||||
childNodes.forEach((el, idx) => {
|
||||
if ((el.nodeType === 1) && el.classList.contains('usa-sr-only')) {
|
||||
prefixIndex = idx;
|
||||
}
|
||||
});
|
||||
|
||||
range.selectNodeContents(copyableElement);
|
||||
if (prefixIndex !== -1) { range.setStart(copyableElement, prefixIndex + 1); }
|
||||
|
||||
return range;
|
||||
};
|
||||
|
||||
this.copyValueToClipboard = function(copyableElement, callback) {
|
||||
var selection = window.getSelection ? window.getSelection() : document.selection,
|
||||
range = this.getRangeFromElement(copyableElement);
|
||||
|
||||
selection.removeAllRanges();
|
||||
selection.addRange(range);
|
||||
document.execCommand('copy');
|
||||
selection.removeAllRanges();
|
||||
callback();
|
||||
/**
|
||||
* Copy text to clipboard using modern Clipboard API
|
||||
* @param {string} text - The text to copy
|
||||
* @param {Function} callback - Called after successful copy
|
||||
*/
|
||||
this.copyValueToClipboard = async function(text, callback) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(text);
|
||||
callback();
|
||||
} catch (err) {
|
||||
console.error('Failed to copy to clipboard:', err);
|
||||
}
|
||||
};
|
||||
|
||||
this.start = function(component) {
|
||||
|
||||
const $component = $(component),
|
||||
stateOptions = {
|
||||
value: $component.data('value'),
|
||||
thing: $component.data('thing')
|
||||
},
|
||||
name = $component.data('name');
|
||||
const value = component.dataset.value;
|
||||
const thing = component.dataset.thing;
|
||||
const name = component.dataset.name;
|
||||
|
||||
// if the name is distinct from the thing:
|
||||
// - it will be used in the rendering
|
||||
// - the value won't be identified by a heading so needs its own label
|
||||
if (name !== stateOptions.thing) {
|
||||
stateOptions.name = name;
|
||||
stateOptions.valueLabel = true;
|
||||
}
|
||||
// Determine button label
|
||||
const isMultiple = name !== thing;
|
||||
const buttonLabel = isMultiple
|
||||
? `Copy ${thing}`
|
||||
: `Copy ${thing} to clipboard`;
|
||||
const srSuffix = isMultiple ? ` for ${name}` : '';
|
||||
|
||||
$component
|
||||
.addClass('copy-to-clipboard')
|
||||
.css('min-height', $component.height())
|
||||
.html(states.valueVisible($.extend({ 'onload': true }, stateOptions)))
|
||||
.on(
|
||||
'click', '.copy-to-clipboard__button--copy', () =>
|
||||
this.copyValueToClipboard(
|
||||
$('.copy-to-clipboard__value', component)[0], () =>
|
||||
$component
|
||||
.html(states.valueCopied(stateOptions))
|
||||
.find('.usa-button').focus()
|
||||
)
|
||||
)
|
||||
.on(
|
||||
'click', '.copy-to-clipboard__button--show', () =>
|
||||
$component
|
||||
.html(states.valueVisible(stateOptions))
|
||||
.find('.usa-button').focus()
|
||||
);
|
||||
// Create simple HTML structure
|
||||
component.classList.add('copy-to-clipboard');
|
||||
component.innerHTML = `
|
||||
<div class="copy-to-clipboard__value">${value}</div>
|
||||
<button class="usa-button usa-button--outline copy-to-clipboard__button" type="button">
|
||||
${buttonLabel}<span class="usa-sr-only">${srSuffix}</span>
|
||||
</button>
|
||||
<span class="usa-sr-only" aria-live="polite" aria-atomic="true"></span>
|
||||
`;
|
||||
|
||||
const button = component.querySelector('.copy-to-clipboard__button');
|
||||
const srAnnouncement = component.querySelector('[aria-live]');
|
||||
|
||||
// Handle copy button click
|
||||
button.addEventListener('click', () => {
|
||||
this.copyValueToClipboard(value, () => {
|
||||
// Change button text to "Copied!"
|
||||
const originalText = button.innerHTML;
|
||||
button.innerHTML = `Copied!<span class="usa-sr-only">${srSuffix}</span>`;
|
||||
button.disabled = true;
|
||||
|
||||
// Announce to screen readers
|
||||
srAnnouncement.textContent = `${thing} copied to clipboard`;
|
||||
|
||||
// Reset button after 2 seconds
|
||||
setTimeout(() => {
|
||||
button.innerHTML = originalText;
|
||||
button.disabled = false;
|
||||
srAnnouncement.textContent = '';
|
||||
}, 2000);
|
||||
});
|
||||
});
|
||||
|
||||
if ('stickAtBottomWhenScrolling' in window.NotifyModules) {
|
||||
window.NotifyModules.stickAtBottomWhenScrolling.recalculate();
|
||||
|
||||
@@ -4,15 +4,13 @@
|
||||
window.NotifyModules['track-error'] = function() {
|
||||
|
||||
this.start = function(element) {
|
||||
var component = $(element);
|
||||
|
||||
// Track error to analytics if available
|
||||
if (window.NotifyModules && window.NotifyModules.analytics && window.NotifyModules.analytics.trackEvent) {
|
||||
window.NotifyModules.analytics.trackEvent(
|
||||
'Error',
|
||||
component.data('error-type'),
|
||||
element.dataset.errorType,
|
||||
{
|
||||
'label': component.data('error-label')
|
||||
'label': element.dataset.errorLabel
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
@@ -74,7 +74,6 @@ import './fileUpload.js';
|
||||
import './errorTracking.js';
|
||||
import './templateFolderForm.js';
|
||||
import './collapsibleCheckboxes.js';
|
||||
import './radioSlider.js';
|
||||
import './updateStatus.js';
|
||||
import './main.js';
|
||||
import './listEntry.js';
|
||||
|
||||
@@ -1,19 +1,23 @@
|
||||
(function (window) {
|
||||
'use strict';
|
||||
|
||||
var $ = window.jQuery;
|
||||
|
||||
window.NotifyModules.moduleSystem = {
|
||||
find: function (container) {
|
||||
container = container || $('body');
|
||||
container = container || document.body;
|
||||
|
||||
var modules;
|
||||
var moduleSelector = '[data-module]';
|
||||
|
||||
modules = container.find(moduleSelector);
|
||||
// If container is already an element, use it directly
|
||||
if (container instanceof Element) {
|
||||
modules = Array.from(container.querySelectorAll(moduleSelector));
|
||||
|
||||
if (container.is(moduleSelector)) {
|
||||
modules = modules.add(container);
|
||||
// If the container itself is a module, include it
|
||||
if (container.matches && container.matches(moduleSelector)) {
|
||||
modules.unshift(container);
|
||||
}
|
||||
} else {
|
||||
modules = Array.from(document.querySelectorAll(moduleSelector));
|
||||
}
|
||||
|
||||
return modules;
|
||||
@@ -25,16 +29,16 @@
|
||||
for (var i = 0, l = modules.length; i < l; i++) {
|
||||
try {
|
||||
var module;
|
||||
var element = $(modules[i]);
|
||||
var type = this.camelCaseAndCapitalise(element.data('module'));
|
||||
var started = element.data('module-started');
|
||||
var element = modules[i];
|
||||
var type = this.camelCaseAndCapitalise(element.dataset.module);
|
||||
var started = element.dataset.moduleStarted;
|
||||
|
||||
if (typeof window.NotifyModules[type] === 'function' && !started) {
|
||||
module = new window.NotifyModules[type]();
|
||||
if (module.start) {
|
||||
module.start(element);
|
||||
}
|
||||
element.data('module-started', true);
|
||||
element.dataset.moduleStarted = 'true';
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to initialize module:', type || 'unknown', error);
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
(function(window) {
|
||||
|
||||
"use strict";
|
||||
|
||||
window.NotifyModules['radio-slider'] = function() {
|
||||
|
||||
this.start = function(component) {
|
||||
|
||||
$(component)
|
||||
.on('click', function() {
|
||||
|
||||
valuesInLabel = $(this).find(':checked').next('label').text().split('/');
|
||||
|
||||
if (valuesInLabel.length === 2) {
|
||||
leftValue = valuesInLabel[0];
|
||||
rightValue = valuesInLabel[1];
|
||||
$(this).find('.radio-slider-left-value').text(leftValue);
|
||||
$(this).find('.radio-slider-right-value').text(rightValue);
|
||||
}
|
||||
|
||||
})
|
||||
.trigger('click');
|
||||
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
})(window);
|
||||
Reference in New Issue
Block a user