__ __ __ __ _____ _ _ _____ _ _ _ | \/ | \ \ / / | __ \ (_) | | / ____| | | | | | \ / |_ __\ V / | |__) | __ ___ ____ _| |_ ___ | (___ | |__ ___| | | | |\/| | '__|> < | ___/ '__| \ \ / / _` | __/ _ \ \___ \| '_ \ / _ \ | | | | | | |_ / . \ | | | | | |\ V / (_| | || __/ ____) | | | | __/ | | |_| |_|_(_)_/ \_\ |_| |_| |_| \_/ \__,_|\__\___| |_____/|_| |_|\___V 2.1 if you need WebShell for Seo everyday contact me on Telegram Telegram Address : @jackleetFor_More_Tools:
import {
createElement,
Component,
useContext,
createContext,
useState,
Fragment,
} from '@wordpress/element'
import classnames from 'classnames'
import {
DndContext,
closestCenter,
PointerSensor,
useSensor,
useSensors,
} from '@dnd-kit/core'
import {
restrictToVerticalAxis,
restrictToParentElement,
} from '@dnd-kit/modifiers'
import {
arrayMove,
SortableContext,
verticalListSortingStrategy,
} from '@dnd-kit/sortable'
import { useSortable } from '@dnd-kit/sortable'
import { __ } from 'ct-i18n'
import LayerControls from './ct-addable-box/LayerControls'
import OptionsPanel from '../OptionsPanel'
import { getValueFromInput } from '../helpers/get-value-from-input'
import nanoid from 'nanoid'
const valueWithUniqueIds = (value) =>
value.map((singleItem) => ({
...singleItem,
...(singleItem.__id
? {}
: {
__id: nanoid(),
}),
}))
const getDefaultState = () => ({
currentlyPickedItem: null,
isDragging: false,
isOpen: false,
})
export const LayersContext = createContext(getDefaultState())
const { Provider, Consumer } = LayersContext
const SortableItem = ({ items, onChange, value, disabled }) => {
const {
attributes,
listeners,
setNodeRef,
transform,
transition,
isDragging,
} = useSortable({
id: value.__id,
disabled,
})
const style = {
transform: transform
? `translate3d(${transform.x}px, ${transform.y}px, 0)`
: undefined,
transition,
zIndex: isDragging ? 9999999 : undefined,
position: isDragging ? 'relative' : undefined,
}
return (
<Consumer>
{({
option,
isDragging: contextIsDragging,
isOpen,
parentValue,
}) => (
<li
ref={setNodeRef}
style={style}
className={classnames('ct-layer', option.itemClass, {
[`ct-disabled`]: !{ enabled: true, ...value }.enabled,
[`ct-active`]:
isOpen === value.__id &&
(!contextIsDragging ||
(contextIsDragging &&
contextIsDragging !== isOpen)),
})}>
<LayerControls
items={items}
onChange={onChange}
value={value}
dragHandleProps={{
...attributes,
...listeners,
style: {
cursor: isDragging ? 'grabbing' : 'grab',
}
}}
/>
{isOpen === value.__id &&
(!contextIsDragging ||
(contextIsDragging &&
contextIsDragging !== isOpen)) && (
<div className="ct-layer-content">
<OptionsPanel
hasRevertButton={false}
parentValue={parentValue}
onChange={(key, newValue) => {
onChange(
items.map((l) =>
l.__id === value.__id
? {
...l,
[key]: newValue,
}
: l
)
)
}}
value={getValueFromInput(
option['inner-options'],
{
...(option.value.filter(
({ id }) => id === value.id
).length > 1
? option.value.filter(
({ id }) =>
value.id === id
)[
items
.filter(
({ id }) =>
id ===
value.id
)
.map(
({ __id }) =>
__id
)
.indexOf(value.__id)
]
: {}),
...value,
}
)}
options={option['inner-options']}
/>
</div>
)}
</li>
)}
</Consumer>
)
}
const Layers = ({ value, option, onChange, values }) => {
const [state, setState] = useState(getDefaultState())
const sensors = useSensors(useSensor(PointerSensor))
const localOnChange = (v) => {
onChange(v)
}
const addForId = (val = {}) => {
localOnChange([
...(value || []),
{
enabled: true,
...getValueFromInput(option['inner-options'] || {}, {}),
...val,
__id: nanoid(),
},
])
}
const computedValue = valueWithUniqueIds(value)
return (
<Provider
value={{
...state,
parentValue: values,
addForId,
option,
removeForId: (idToRemove) =>
localOnChange(
valueWithUniqueIds(value).filter(
({ __id: id }) => id !== idToRemove
)
),
toggleOptionsPanel: (idToAdd) => {
if (value.length > 0 && !value[0].__id) {
localOnChange(computedValue)
}
setState((state) => ({
...state,
isOpen: state.isOpen === idToAdd ? false : idToAdd,
}))
},
}}>
<DndContext
sensors={sensors}
collisionDetection={closestCenter}
modifiers={[restrictToVerticalAxis, restrictToParentElement]}
onDragEnd={(event) => {
const { active, over } = event
if (!over) {
return
}
if (active.id !== over.id) {
const oldIndex = computedValue.findIndex(
(item) => item.__id === active.id
)
const newIndex = computedValue.findIndex(
(item) => item.__id === over.id
)
localOnChange(
arrayMove(computedValue, oldIndex, newIndex)
)
}
setState((state) => ({
...state,
isDragging: false,
}))
}}
onDragStart={(event) => {
const { active } = event
if (value.length > 0 && !value[0].__id) {
wp.customize &&
wp.customize.previewer &&
wp.customize.previewer.send(
'ct:sync:refresh_partial',
{
shouldSkip: true,
}
)
localOnChange(computedValue)
}
setState((state) => ({
...state,
isDragging: active.id,
}))
}}>
<SortableContext
items={computedValue.map((item) => item.__id)}
strategy={verticalListSortingStrategy}>
<Consumer>
{({ option }) => (
<ul className="ct-layers">
{computedValue.map((value, index) => (
<SortableItem
key={value.__id}
onChange={(v) => {
localOnChange(v)
}}
value={value}
items={computedValue}
disabled={!!option.disableDrag}
/>
))}
</ul>
)}
</Consumer>
</SortableContext>
</DndContext>
<button
className="button"
onClick={(e) => {
e.preventDefault()
addForId()
}}>
{__('Add New Item', 'blocksy')}
</button>
</Provider>
)
}
export default Layers
| Name | Type | Size | Permission | Actions |
|---|---|---|---|---|
| background | Folder | 0750 |
|
|
| box-shadow | Folder | 0750 |
|
|
| color-palettes | Folder | 0750 |
|
|
| color-picker | Folder | 0750 |
|
|
| ct-addable-box | Folder | 0750 |
|
|
| ct-layers | Folder | 0750 |
|
|
| ct-number | Folder | 0750 |
|
|
| ct-radio | Folder | 0750 |
|
|
| ct-select | Folder | 0750 |
|
|
| ct-slider | Folder | 0750 |
|
|
| ct-spacing | Folder | 0750 |
|
|
| ct-switch | Folder | 0750 |
|
|
| ratio | Folder | 0750 |
|
|
| text | Folder | 0750 |
|
|
| typography | Folder | 0750 |
|
|
| ct-addable-box.js | File | 6.16 KB | 0640 |
|
| ct-background.js | File | 5.46 KB | 0640 |
|
| ct-border.js | File | 2.75 KB | 0640 |
|
| ct-box-shadow.js | File | 2.64 KB | 0640 |
|
| ct-button.js | File | 456 B | 0640 |
|
| ct-checkboxes.js | File | 1.91 KB | 0640 |
|
| ct-color-palettes-mirror.js | File | 1000 B | 0640 |
|
| ct-color-palettes-picker.js | File | 6.71 KB | 0640 |
|
| ct-color-picker.js | File | 2.71 KB | 0640 |
|
| ct-customize-section-title-actions.js | File | 6.74 KB | 0640 |
|
| ct-customizer-reset-options.js | File | 1.83 KB | 0640 |
|
| ct-divider.js | File | 328 B | 0640 |
|
| ct-entity-picker.js | File | 2.38 KB | 0640 |
|
| ct-file-uploader.js | File | 2 KB | 0640 |
|
| ct-footer-builder.js | File | 5.96 KB | 0640 |
|
| ct-header-builder.js | File | 272 B | 0640 |
|
| ct-image-picker.js | File | 1.81 KB | 0640 |
|
| ct-image-uploader.js | File | 10.12 KB | 0640 |
|
| ct-layers-combined.js | File | 2.22 KB | 0640 |
|
| ct-layers-mirror.js | File | 1.15 KB | 0640 |
|
| ct-layers.js | File | 5.39 KB | 0640 |
|
| ct-multi-image-uploader.js | File | 3.14 KB | 0640 |
|
| ct-notification.js | File | 378 B | 0640 |
|
| ct-number.js | File | 454 B | 0640 |
|
| ct-panel.js | File | 8.88 KB | 0640 |
|
| ct-radio.js | File | 401 B | 0640 |
|
| ct-ratio.js | File | 6.87 KB | 0640 |
|
| ct-select.js | File | 669 B | 0640 |
|
| ct-slider.js | File | 14.14 KB | 0640 |
|
| ct-spacer.js | File | 386 B | 0640 |
|
| ct-spacing.js | File | 5.09 KB | 0640 |
|
| ct-switch.js | File | 508 B | 0640 |
|
| ct-timer.js | File | 3.27 KB | 0640 |
|
| ct-title.js | File | 562 B | 0640 |
|
| ct-typography.js | File | 7.35 KB | 0640 |
|
| ct-visibility.js | File | 4.76 KB | 0640 |
|
| ct-woocommerce-columns-and-rows.js | File | 3 KB | 0640 |
|
| ct-woocommerce-ratio.js | File | 1.66 KB | 0640 |
|
| date-time-picker.js | File | 811 B | 0640 |
|
| hidden.js | File | 243 B | 0640 |
|
| html.js | File | 264 B | 0640 |
|
| jsx.js | File | 237 B | 0640 |
|
| react-outside-click-handler.js | File | 3.17 KB | 0640 |
|
| text.js | File | 384 B | 0640 |
|
| textarea.js | File | 518 B | 0640 |
|
| wp-editor.js | File | 3.67 KB | 0640 |
|