prefix-icon="calendar-icon"
function combine($ids, $keys, ...$values) {
return array_combine(
$ids,
array_map(
fn($i) => array_combine($keys, array_column($values, $i)),
array_keys($ids)
)
);
}
$result = combine($input, $params, $array1, $array2);
function parseDate(str) {
const months = Array.from(
{ length: 12 },
(_, i) => new Date(0, i).toLocaleString('ru-RU', { month: 'long' })
);
const [ , month, day, year, hour, minute ] = str.match(/(\S+) (\d+), (\d+) (\d+):(\d+)/);
return +new Date(
year,
months.indexOf(month.toLowerCase()),
day,
hour,
minute
);
}
const Checkbox = forwardRef(({ label, ...props }, ref) =>
<label>
<input type="checkbox" ref={ref} {...props} />
{label}
</label>
);
function CheckboxGroup({
items,
label = item => item,
selected,
setSelected,
}) {
const onChange = ({ target: { checked, dataset: { index } } }) =>
setSelected(selected => checked
? [ ...selected, items[index] ]
: selected.filter(n => n !== items[index])
);
const allSelectedRef = useRef();
const onAllSelectedChange = ({ target: { checked } }) =>
setSelected(checked ? [...items] : []);
useEffect(() => {
const isAllSelected = items.length === selected.length;
allSelectedRef.current.checked = isAllSelected;
allSelectedRef.current.indeterminate = !isAllSelected && !!selected.length;
}, [ selected ]);
return (
<div className="checkbox-group">
<Checkbox
label="SELECT ALL"
defaultChecked={false}
onChange={onAllSelectedChange}
ref={allSelectedRef}
/>
{items.map((n, i) => (
<Checkbox
label={label(n)}
data-index={i}
checked={selected.includes(n)}
onChange={onChange}
/>
))}
</div>
);
}
:not
), проверяем фильтруемые элементы на соответствие селектору:document.querySelector('.options').addEventListener('change', e => {
const [ not, has ] = Array.prototype.reduce.call(
e.currentTarget.querySelectorAll('input'),
(acc, n) => (acc[+n.checked].push(`.${n.value}`), acc),
[ [], [] ]
);
const selector = `${has.join('')}:not(${not.join(',')})`;
for (const n of document.querySelector('.box').children) {
n.classList.toggle('hidden', !n.matches(selector));
}
});
const checkboxes = [...document.querySelectorAll('.options input')];
const items = [...document.querySelector('.box').children];
checkboxes.forEach(n => n.addEventListener('change', onChange));
function onChange() {
items.forEach(({ classList: cl }) => {
cl.toggle('hidden', checkboxes.some(n => n.checked !== cl.contains(n.value)));
});
}
const blocks = ref(Array.from({ length: 5 }, (_, i) => (-~i) ** 2));
const active = ref(0);
function next() {
active.value = (active.value + 1 + blocks.value.length) % blocks.value.length;
}
let intervalId = null;
onMounted(() => intervalId = setInterval(next, 500));
onUnmounted(() => clearInterval(intervalId));
<div
v-for="(n, i) in blocks"
v-text="n"
:class="[ 'box-item', { active: i === active } ]"
></div>
:nth-child
- не круто. Лучше сделать компонент, принимающий массив цветов и создающий блоки на его основе. Соответственно, вместо класса будет назначаться цвет фона напрямую, как-то так:<div
v-for="(n, i) in colors"
:style="{ backgroundColor: i === active ? n : '' }"
...
почему при изменении даты передаваемой в пропс не обновляется значение в самом компоненте таймера?
targetDate
при изменении props.date
. Нет, можете себя не утруждать - ничего такого у вас нет.targetDate
, рассчитываем дни-часы-минуты-секунды сразу на основе props.date
- так при изменении props.date
не придётся предпринимать никаких дополнительных телодвижений, всё посчитается как надо при следующем вызове updateCountdown
. Вот как-то так. .dropdown.show {
display: block;
}
const accordionItemSelector = '.data-accordion--summary-container';
const contentSelector = '.dropdown';
const activeClass = 'show';
document.body.addEventListener('click', ({ target: t }) => {
if (t.matches(accordionItemSelector)) {
document.querySelectorAll(contentSelector).forEach(n => {
if (!n.contains(t) && !t.contains(n)) {
n.classList.remove(activeClass);
};
});
t.querySelector(contentSelector).classList.toggle(activeClass);
}
});
- acc[key] = [value];
+ (acc[key] ??= []).push(value);
const convertQueryStringToObject = str => Array
.from(new URLSearchParams(str))
.reduce((acc, n) => ((acc[n[0]] ??= []).push(n[1]), acc), {});
const convertQueryStringToObject = str => Array
.from(str.matchAll(/([^&]+)=([^&]+)/g))
.reduce((acc, [ , k, v ]) => (
Object.hasOwn(acc, k) || (acc[k] = []),
acc[k][acc[k].length] = v,
acc
), {});
.no-overflow {
overflow: hidden;
}
mounted() {
this.$watch(
() => this.isModalAddVisible || this.activeId,
val => document.body.classList.toggle('no-overflow', val),
{ immediate: true }
);
},
transition-group
. Вот так всё просто.