runtimeGroupsJs top-level constant

String const runtimeGroupsJs

Implementation

const String runtimeGroupsJs = r'''
function groupRoot(groupId) {
  return document.querySelector('[data-arcane-group="' + cssEscape(groupId) +
    '"][data-arcane-group-mode]');
}

function groupValues(groupId) {
  const root = groupRoot(groupId);
  if (!root) return [];
  const raw = root.getAttribute('data-arcane-group-value') || '';
  if (!raw) return [];
  return raw.split('\u001f').filter(Boolean);
}

function groupMode(groupId) {
  const root = groupRoot(groupId);
  if (!root) return 'single';
  return root.getAttribute('data-arcane-group-mode') || 'single';
}

function setGroupRawValues(groupId, values) {
  const root = groupRoot(groupId);
  if (!root) return;
  root.setAttribute('data-arcane-group-value', values.join('\u001f'));
  syncGroupItems(groupId, values);
  fireEvent(root, 'arcane:change', { groupId: groupId, value: values });
  const changeAction = root.getAttribute('data-arcane-group-change');
  if (changeAction) {
    runActions(changeAction, { trigger: root, groupId: groupId, value: values });
  }
}

function syncGroupItems(groupId, values) {
  const root = groupRoot(groupId);
  if (!root) return;
  const items = document.querySelectorAll(
    '[data-arcane-group="' + cssEscape(groupId) + '"][data-arcane-value]'
  );
  for (let i = 0; i < items.length; i++) {
    const item = items[i];
    if (item === root) continue;
    const v = item.getAttribute('data-arcane-value');
    const selected = values.indexOf(v) >= 0;
    item.setAttribute('data-arcane-state', selected ? 'selected' : 'unselected');
    if (item.getAttribute('role') === 'option' || item.getAttribute('role') === 'menuitemcheckbox' ||
        item.getAttribute('role') === 'menuitemradio') {
      item.setAttribute('aria-selected', selected ? 'true' : 'false');
      item.setAttribute('aria-checked', selected ? 'true' : 'false');
    }
    if (item.tagName === 'INPUT' && (item.type === 'checkbox' || item.type === 'radio')) {
      item.checked = selected;
    }
  }
}

function setGroupValue(groupId, value) {
  const mode = groupMode(groupId);
  if (mode === 'multi') {
    setGroupRawValues(groupId, value ? [value] : []);
  } else {
    setGroupRawValues(groupId, value ? [value] : []);
  }
}

function toggleGroupValue(groupId, value) {
  const mode = groupMode(groupId);
  const cur = groupValues(groupId);
  if (mode === 'multi') {
    const idx = cur.indexOf(value);
    let next;
    if (idx >= 0) {
      next = cur.slice();
      next.splice(idx, 1);
    } else {
      const root = groupRoot(groupId);
      const max = root ? parseInt(root.getAttribute('data-arcane-group-max') || '0', 10) : 0;
      if (max > 0 && cur.length >= max) {
        next = cur.slice(1);
        next.push(value);
      } else {
        next = cur.concat([value]);
      }
    }
    setGroupRawValues(groupId, next);
  } else {
    if (cur.length === 1 && cur[0] === value) {
      const root = groupRoot(groupId);
      if (root && root.getAttribute('data-arcane-group-required') === 'true') return;
      setGroupRawValues(groupId, []);
    } else {
      setGroupRawValues(groupId, [value]);
    }
  }
}

function clearGroup(groupId) {
  setGroupRawValues(groupId, []);
}

ARCANE.groups.values = groupValues;
ARCANE.groups.mode = groupMode;
ARCANE.groups.set = setGroupValue;
ARCANE.groups.toggle = toggleGroupValue;
ARCANE.groups.clear = clearGroup;
''';