✨ Add new palette UI
|
@ -448,25 +448,37 @@
|
|||
path)
|
||||
name))
|
||||
|
||||
(defn merge-path-item-with-dot
|
||||
"Put the item at the end of the path."
|
||||
[path name]
|
||||
(if-not (empty? path)
|
||||
(if-not (empty? name)
|
||||
(str path "\u00A0\u2022\u00A0" name)
|
||||
path)
|
||||
name))
|
||||
|
||||
(defn compact-path
|
||||
"Separate last item of the path, and truncate the others if too long:
|
||||
'one' -> ['' 'one' false]
|
||||
'one / two / three' -> ['one / two' 'three' false]
|
||||
'one / two / three / four' -> ['one / two / ...' 'four' true]
|
||||
'one-item-but-very-long / two' -> ['...' 'two' true] "
|
||||
[path max-length]
|
||||
[path max-length dot?]
|
||||
(let [path-split (split-path path)
|
||||
last-item (last path-split)]
|
||||
last-item (last path-split)
|
||||
merge-path (if dot?
|
||||
merge-path-item-with-dot
|
||||
merge-path-item)]
|
||||
(loop [other-items (seq (butlast path-split))
|
||||
other-path ""]
|
||||
(if-let [item (first other-items)]
|
||||
(let [full-path (-> other-path
|
||||
(merge-path-item item)
|
||||
(merge-path-item last-item))]
|
||||
(merge-path item)
|
||||
(merge-path last-item))]
|
||||
(if (> (count full-path) max-length)
|
||||
[(merge-path-item other-path "...") last-item true]
|
||||
[(merge-path other-path "...") last-item true]
|
||||
(recur (next other-items)
|
||||
(merge-path-item other-path item))))
|
||||
(merge-path other-path item))))
|
||||
[other-path last-item false]))))
|
||||
|
||||
(defn compact-name
|
||||
|
|
3
frontend/resources/images/icons/detach-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10 4.667h2c.438 0 .871.086 1.276.253a3.342 3.342 0 011.804 1.804 3.345 3.345 0 010 2.552 3.343 3.343 0 01-1.804 1.804 3.345 3.345 0 01-1.276.253h-2m-4 0H4c-.438 0-.871-.086-1.276-.253A3.333 3.333 0 014 4.667h2m-.667 3.326h5.334z"/>
|
||||
</svg>
|
After (image error) Size: 357 B |
|
@ -1,3 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2 9.75C2 9.06 2.56 8.5 3.25 8.5H10M2 9.75C2 10.44 2.56 11 3.25 11H10V1H3.25C2.56 1 2 1.56 2 2.25V9.75Z"/>
|
||||
<path d="M2.667 13c0 .92.746 1.667 1.666 1.667h9V1.333h-9c-.92 0-1.666.747-1.666 1.667v10zm0 0c0-.92.746-1.667 1.666-1.667h9"/>
|
||||
</svg>
|
||||
|
|
Before (image error) Size: 235 B After (image error) Size: 247 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M11.333 12H2m12-8H2m6.667 4H2"/>
|
||||
</svg>
|
After (image error) Size: 161 B |
3
frontend/resources/images/icons/text-LTR-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.72 2.333H9.28c-1.788 0-3.333 1.493-3.333 3.334S7.492 9 9.28 9h2m0-6.667v11.334m2-11.334v11.334m-12-7.334l2 2-2 2"/>
|
||||
</svg>
|
After (image error) Size: 248 B |
3
frontend/resources/images/icons/text-RTL-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14.72 2.333H9.28c-1.788 0-3.333 1.493-3.333 3.334S7.492 9 9.28 9h2m0-6.667v11.334m2-11.334v11.334m-10-7.334l-2 2 2 2"/>
|
||||
</svg>
|
After (image error) Size: 249 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M11.333 12H2m12-8H2m6.667 4H2"/>
|
||||
</svg>
|
After (image error) Size: 161 B |
3
frontend/resources/images/icons/text-bottom-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M10 3L8 5 6 3m6.667 10H3.333m9.334-2.667H3.333"/>
|
||||
</svg>
|
After (image error) Size: 178 B |
3
frontend/resources/images/icons/text-fixed-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M5.667 10.667l.863-1.918m0 0l1.537-3.416 1.536 3.416m-3.073 0h3.073m0 0l.864 1.918M1.333 3.333c0-1.103.897-2 2-2h9.334c1.103 0 2 .897 2 2v9.334c0 1.103-.897 2-2 2H3.333c-1.103 0-2-.897-2-2V3.333z"/>
|
||||
</svg>
|
After (image error) Size: 327 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M14 8H2m12-4H2m12 8H2"/>
|
||||
</svg>
|
After (image error) Size: 153 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M2.667 14l-1.334-1.333m0 0l1.334-1.333m-1.334 1.333h13.334M13.333 14l1.334-1.333m0 0l-1.334-1.333M2.5 8l.959-2.157m0 0L5.167 2l1.708 3.843m-3.416 0h3.416m0 0L7.833 8m.834-6.5l2.666 6L14 1.5"/>
|
||||
</svg>
|
After (image error) Size: 321 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M8.333 3.333H15M8.333 8H15m-6.667 4.667H15M1 4l2-2 2 2m-4 8l2 2 2-2M3 2.667v10.666"/>
|
||||
</svg>
|
After (image error) Size: 214 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M9 7.333c0-1.031.689-2 2.167-2 1.478 0 2.166.969 2.166 2v.655m0 .178v2.167c0 1.334 1.334 1.334 1.334 1.334m-13-4.334c0-1.031.688-2 2.166-2S6 6.302 6 7.333v.655m0 .178v2.167c0 1.334 1.333 1.334 1.333 1.334m3.334.333c1.021 0 2.616-.352 2.665-3.832L13.333 8c0 .727-1.889.667-2.666.667-1.334 0-2 .666-2 1.666 0 1 .963 1.667 2 1.667zm-7.334 0c1.021 0 2.616-.352 2.666-3.832L6 8c0 .727-1.889.667-2.667.667-1.333 0-2 .666-2 1.666 0 1 .963 1.667 2 1.667z"/>
|
||||
</svg>
|
After (image error) Size: 578 B |
3
frontend/resources/images/icons/text-middle-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M6 14l2-2 2 2M3.333 6.667h9.334M3.333 9.333h9.334M10 2L8 4 6 2"/>
|
||||
</svg>
|
After (image error) Size: 194 B |
3
frontend/resources/images/icons/text-mixed-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 12l1.318-2.877m0 0L4.333 4l2.348 5.123m-4.696 0h4.696m0 0L8 12m1.667-4.667c0-1.031.688-2 2.166-2s2.167.969 2.167 2v.655m0 .178v2.167c0 1.334 1.333 1.334 1.333 1.334m-4 .333c1.021 0 2.616-.352 2.666-3.832L14 8c0 .727-1.889.667-2.667.667-1.333 0-2 .666-2 1.666 0 1 .963 1.667 2 1.667z"/>
|
||||
</svg>
|
After (image error) Size: 420 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M11.444 3.533C9.96.878 5 1.48 5 4.667c0 1.333 1 2 1 2m-1.482 4.3c.99 3.185 6.926 2.826 6.926-.531 0-1.317-1.249-2.61-2.503-2.621m0 0h4.392m-4.392 0H2"/>
|
||||
</svg>
|
After (image error) Size: 281 B |
3
frontend/resources/images/icons/text-top-refactor.svg
Normal file
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M6 13l2-2 2 2M3.333 3h9.334M3.333 5.667h9.334"/>
|
||||
</svg>
|
After (image error) Size: 177 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M11.333 2.667v4.666a3.334 3.334 0 11-6.666 0V2.667M12 14H4"/>
|
||||
</svg>
|
After (image error) Size: 190 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M.667 12l1.318-2.877m0 0L4.333 4l2.348 5.123m-4.696 0h4.696m0 0L8 12l1.319-2.877m0 0L11.667 4l2.348 5.123m-4.696 0h4.696m0 0L15.333 12"/>
|
||||
</svg>
|
After (image error) Size: 266 B |
|
@ -0,0 +1,3 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" stroke-linecap="round" stroke-linejoin="round">
|
||||
<path d="M5.333 4H14M5.333 8H14m-8.667 4H14M1.333 4h1.334M1.333 8h1.334m-1.334 4h1.334"/>
|
||||
</svg>
|
After (image error) Size: 209 B |
|
@ -7,18 +7,24 @@
|
|||
.button-primary {
|
||||
@include buttonStyle;
|
||||
@include flexCenter;
|
||||
background-color: var(--button-primary-background-color-rest);
|
||||
border: $s-1 solid var(--button-primary-border-color-rest);
|
||||
color: var(--button-primary-foreground-color-rest);
|
||||
&:hover {
|
||||
background-color: var(--button-background-hover);
|
||||
background-color: var(--button-primary-background-color-hover);
|
||||
border: $s-1 solid var(--button-primary-border-color-hover);
|
||||
color: var(--button-primary-foreground-color-hover);
|
||||
svg {
|
||||
stroke: var(--button-foreground-hover);
|
||||
stroke: var(--button-primary-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
border: 1px solid var(--button-border-focus);
|
||||
background-color: var(--button-background-focus);
|
||||
background-color: var(--button-primary-background-color-focus);
|
||||
border: $s-1 solid var(--button-primary-boder-color-focus);
|
||||
color: var(--button-primary-foreground-color-focus);
|
||||
svg {
|
||||
stroke: var(--button-foreground-focus);
|
||||
stroke: var(--button-primary-foreground-color-focus);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
|
@ -32,6 +38,73 @@
|
|||
}
|
||||
|
||||
.button-secondary {
|
||||
@include buttonStyle;
|
||||
@include flexCenter;
|
||||
background-color: var(--button-secondary-background-color-rest);
|
||||
border: $s-1 solid var(--button-secondary-border-color-rest);
|
||||
color: var(--button-secondary-foreground-color-rest);
|
||||
&:hover {
|
||||
background-color: var(--button-secondary-background-color-hover);
|
||||
border: $s-1 solid var(--button-secondary-border-color-hover);
|
||||
color: var(--button-secondary-foreground-color-hover);
|
||||
svg,
|
||||
span svg {
|
||||
stroke: var(--button-secondary-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
background-color: var(--button-secondary-background-color-focus);
|
||||
border: $s-1 solid var(--button-secondary-boder-color-focus);
|
||||
color: var(--button-secondary-foreground-color-focus);
|
||||
svg {
|
||||
stroke: var(--button-secondary-foreground-color-focus);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
&:focus-visible {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.button-tertiary {
|
||||
@include buttonStyle;
|
||||
@include flexCenter;
|
||||
color: var(--button-tertiary-foreground-color-rest);
|
||||
svg {
|
||||
stroke: var(--button-tertiary-foreground-color-rest);
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--button-tertiary-background-color-hover);
|
||||
color: var(--button-tertiary-foreground-color-hover);
|
||||
svg {
|
||||
stroke: var(--button-tertiary-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
outline: none;
|
||||
border: $s-1 solid var(--button-tertiary-border-color-focus);
|
||||
background-color: var(--button-tertiary-background-color-focus);
|
||||
color: var(--button-tertiary-foreground-color-focus);
|
||||
svg {
|
||||
stroke: var(--button-tertiary-foreground-color-focus);
|
||||
}
|
||||
}
|
||||
&:active {
|
||||
border: $s-1 solid var(--button-tertiary-border-color-focus);
|
||||
outline: none;
|
||||
}
|
||||
&:focus-visible {
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
|
||||
.button-tag {
|
||||
@include buttonStyle;
|
||||
@include flexCenter;
|
||||
&:hover {
|
||||
|
@ -73,3 +146,20 @@
|
|||
width: $s-12;
|
||||
stroke-width: 1.33px;
|
||||
}
|
||||
|
||||
.asset-element {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-32;
|
||||
border-radius: $br-8;
|
||||
margin-bottom: $s-4;
|
||||
padding: $s-8 $s-12;
|
||||
background-color: var(--assets-item-background-color);
|
||||
color: var(--assets-item-name-foreground-color);
|
||||
&:hover,
|
||||
&:focus-within {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,15 +8,53 @@
|
|||
.light,
|
||||
.default {
|
||||
--scrollbar-background-color: var(--color-foreground-secondary);
|
||||
--button-background-active: var(--color-background-primary);
|
||||
|
||||
--button-background-hover: var(--color-background-quaternary);
|
||||
--button-foreground-hover: var(--color-accent-primary);
|
||||
--button-foreground-active: var(--color-foreground-primary);
|
||||
--button-background-focus: var(--color-background-secondary);
|
||||
--button-foreground-focus: var(--color-foreground-primary);
|
||||
--button-border-focus: var(--color-accent-primary);
|
||||
--button-border: var(--color-background-tertiary);
|
||||
--button-foreground-color-disabled: var(--color-background-quaternary);
|
||||
|
||||
--button-primary-background-color-rest: var(--color-accent-primary);
|
||||
--button-primary-border-color-rest: var(--color-accent-primary);
|
||||
--button-primary-foreground-color-rest: var(--color-background-secondary);
|
||||
--button-primary-background-color-hover: var(--color-accent-tertiary);
|
||||
--button-primary-border-color-hover: var(--color-accent-tertiary);
|
||||
--button-primary-foreground-color-hover: var(--color-background-secondary);
|
||||
--button-primary-background-color-selected: var(--color-background-secondary);
|
||||
--button-primary-border-color-selected: var(--color-background-secondary);
|
||||
--button-primary-foreground-color-selected: var(--color-accent-primary);
|
||||
--button-primary-background-color-focus: var(--color-background-tertiary);
|
||||
--button-primary-border-color-focus: var(--color-accent-primary);
|
||||
--button-primary-foreground-color-focus: var(--color-foreground-secondary);
|
||||
|
||||
--button-secondary-background-color-rest: var(--color-background-tertiary);
|
||||
--button-secondary-border-color-rest: var(--color-background-quaternary);
|
||||
--button-secondary-foreground-color-rest: var(--color-foreground-secondary);
|
||||
--button-secondary-background-color-hover: var(--color-background-quaternary);
|
||||
--button-secondary-border-color-hover: var(--color-background-quaternary);
|
||||
--button-secondary-foreground-color-hover: var(--color-accent-primary);
|
||||
--button-secondary-background-color-selected: var(--color-background-secondary);
|
||||
--button-secondary-border-color-selected: var(--color-background-quaternary);
|
||||
--button-secondary-foreground-color-selected: var(--color-accent-primary);
|
||||
--button-secondary-background-color-focus: var(--color-background-tertiary);
|
||||
--button-secondary-border-color-focus: var(--color-accent-primary);
|
||||
--button-secondary-foreground-color-focus: var(--color-foreground-secondary);
|
||||
|
||||
--button-tertiary-foreground-color-rest: var(--color-foreground-secondary);
|
||||
--button-tertiary-background-color-hover: var(--color-background-quaternary);
|
||||
--button-tertiary-border-color-hover: var(--color-background-quaternary);
|
||||
--button-tertiary-foreground-color-hover: var(--color-accent-primary);
|
||||
--button-tertiary-background-color-selected: var(--color-background-secondary);
|
||||
--button-tertiary-border-color-selected: var(--color-background-quaternary);
|
||||
--button-tertiary-foreground-color-selected: var(--color-accent-primary);
|
||||
--button-tertiary-background-color-focus: var(--color-background-tertiary);
|
||||
--button-tertiary-border-color-focus: var(--color-accent-primary);
|
||||
--button-tertiary-foreground-color-focus: var(--color-foreground-primary);
|
||||
|
||||
--icon-foreground: var(--color-foreground-secondary);
|
||||
--icon-foreground-hover: var(--color-foreground-primary);
|
||||
|
||||
|
@ -29,6 +67,7 @@
|
|||
--title-background-color: var(--color-background-secondary);
|
||||
--title-foreground-color: var(--color-foreground-secondary);
|
||||
--title-foreground-color-hover: var(--color-foreground-primary);
|
||||
--title-background-color: var(--color-background-primary);
|
||||
|
||||
--layer-row-background-color: var(--color-background-primary);
|
||||
--layer-row-background-color-hover: var(--color-background-secondary);
|
||||
|
@ -44,13 +83,17 @@
|
|||
--layer-child-row-foreground-color: var(--color-foreground-secondary);
|
||||
--layer-row-component-foreground-color: var(--color-accent-secondary);
|
||||
|
||||
--search-bar-background-color: var(--color-background-primary);
|
||||
--search-bar-input-background-color: var(--color-background-tertiary);
|
||||
--search-bar-input-border-color: var(--color-background-tertiary);
|
||||
|
||||
--input-background-color: var(--color-background-tertiary);
|
||||
--input-background-color-active: var(--color-background-primary);
|
||||
--input-background-color-hover: var(--color-background-quaternary);
|
||||
--input-background-color-focus: var(--color-background-tertiary);
|
||||
--input-background-color-disabled: var(--color-background-primary);
|
||||
--input-placeholder-color: var(--color-foreground-secondary);
|
||||
--input-foreground-color: var(--color-foreground-primary);
|
||||
--input-foreground-color: var(--color-foreground-secondary);
|
||||
--input-foreground-color-active: var(--color-foreground-primary);
|
||||
--input-border-color-active: var(--color-accent-primary);
|
||||
--input-border-outline-color-active: var(--color-accent-primary-muted);
|
||||
|
@ -95,4 +138,26 @@
|
|||
--color-bullet-background-color: var(--white); // We don't want this color to change with palette
|
||||
--color-bullet-border-color: var(--color-background-quaternary);
|
||||
--palette-handler-background-color: var(--color-background-quaternary);
|
||||
|
||||
--assets-item-background-color: var(--color-background-tertiary);
|
||||
--assets-item-background-color-hover: var(--color-background-quaternary);
|
||||
--assets-item-name-foreground-color: var(--color-foreground-secondary);
|
||||
--assets-item-name-foreground-color-hover: var(--color-foreground-primary);
|
||||
--assets-item-border-color: var(--color-accent-primary);
|
||||
--assets-item-background-color-drag: var(--color-accent-primary-muted);
|
||||
--assets-item-border-color-drag: var(--color-accent-primary);
|
||||
--assets-component-background-color: var(--white); // We don't want this color to change with palette
|
||||
|
||||
--radio-btns-background-color: var(--color-background-tertiary);
|
||||
--radio-btn-background-color-selected: var(--color-background-primary);
|
||||
--radio-btn-foreground-color: var(--color-foreground-secondary);
|
||||
--radio-btn-foreground-color-selected: var(--color-accent-primary);
|
||||
--radio-btn-border-color-selected: var(--color-background-quaternary);
|
||||
|
||||
--modal-background-color: var(--color-background-primary);
|
||||
|
||||
--library-name-foreground-color: var(--color-foreground-primary);
|
||||
--library-content-foreground-color: var(--color-foreground-secondary);
|
||||
|
||||
--dropdown-background-color: var(--color-background-tertiary);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@ $fs-9: math.div(9, $fs-base) + rem;
|
|||
$fs-10: math.div(10, $fs-base) + rem;
|
||||
$fs-12: math.div(12, $fs-base) + rem;
|
||||
$fs-14: math.div(14, $fs-base) + rem;
|
||||
$fs-16: math.div(16, $fs-base) + rem;
|
||||
$fs-19: math.div(19, $fs-base) + rem;
|
||||
$fs-25: math.div(25, $fs-base) + rem;
|
||||
$fs-33: math.div(33, $fs-base) + rem;
|
||||
|
|
|
@ -15,6 +15,11 @@
|
|||
background: none;
|
||||
cursor: pointer;
|
||||
}
|
||||
@mixin removeInputStyle {
|
||||
border: none;
|
||||
background: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
@mixin tabTitleTipography {
|
||||
font-family: "worksans", sans-serif;
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
@use "sass:math";
|
||||
|
||||
$s-0: 0px;
|
||||
$s-1: 1px;
|
||||
$s-2: math.div(0.25rem, 2);
|
||||
$s-4: var(--s-4);
|
||||
$s-6: calc($s-2 + $s-4);
|
||||
|
@ -29,13 +30,22 @@ $s-68: calc(var(--s-4) * 17);
|
|||
$s-72: calc(var(--s-4) * 18);
|
||||
$s-76: calc(var(--s-4) * 19);
|
||||
$s-80: calc(var(--s-4) * 20);
|
||||
$s-84: calc(var(--s-4) * 21);
|
||||
$s-92: calc(var(--s-4) * 23);
|
||||
$s-96: calc(var(--s-4) * 24);
|
||||
$s-104: calc(var(--s-4) * 25);
|
||||
$s-120: calc(var(--s-4) * 30);
|
||||
$s-136: calc(var(--s-4) * 34);
|
||||
$s-152: calc(var(--s-4) * 38);
|
||||
$s-192: calc(var(--s-4) * 48);
|
||||
$s-196: calc(var(--s-4) * 49);
|
||||
$s-200: calc(var(--s-4) * 50);
|
||||
$s-216: calc(var(--s-4) * 54);
|
||||
$s-240: calc(var(--s-4) * 60);
|
||||
$s-248: calc(var(--s-4) * 61);
|
||||
$s-248: calc(var(--s-4) * 62);
|
||||
$s-256: calc(var(--s-4) * 64);
|
||||
$s-348: calc(var(--s-4) * 87);
|
||||
$s-400: calc(var(--s-4) * 100);
|
||||
$s-480: calc(var(--s-4) * 120);
|
||||
$s-664: calc(var(--s-4) * 166);
|
||||
$s-736: calc(var(--s-4) * 184);
|
||||
|
|
|
@ -16,4 +16,5 @@
|
|||
--color-accent-primary-muted: var(--green-30);
|
||||
--color-accent-secondary: var(--lilac);
|
||||
--color-accent-tertiary: var(--strong-green);
|
||||
--overlay-color: rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
|
|
@ -9,3 +9,4 @@ $z-index-2: 2;
|
|||
$z-index-4: 4;
|
||||
$z-index-10: 10;
|
||||
$z-index-20: 20;
|
||||
$z-index-modal: 30; // When refactor finish we can reduce this number,
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
(ns app.main.ui
|
||||
(:require
|
||||
[app.config :as cf]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.auth :refer [auth]]
|
||||
|
@ -37,8 +38,10 @@
|
|||
(mf/defc main-page
|
||||
{::mf/wrap [#(mf/catch % {:fallback on-main-error})]}
|
||||
[{:keys [route profile]}]
|
||||
(let [{:keys [data params]} route]
|
||||
(let [{:keys [data params]} route
|
||||
new-css-system (features/use-feature :new-css-system)]
|
||||
[:& (mf/provider ctx/current-route) {:value route}
|
||||
[:& (mf/provider ctx/new-css-system) {:value new-css-system}
|
||||
(case (:name data)
|
||||
(:auth-login
|
||||
:auth-register
|
||||
|
@ -131,7 +134,7 @@
|
|||
:page-id page-id
|
||||
:layout-name layout
|
||||
:key file-id}])
|
||||
nil)]))
|
||||
nil)]]))
|
||||
|
||||
(mf/defc app
|
||||
[]
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"button-primary":"components_color_bullet_new_button-primary_pDkQg","button-secondary":"components_color_bullet_new_button-secondary_y3A8V","button-icon":"components_color_bullet_new_button-icon_uAC1e","button-icon-small":"components_color_bullet_new_button-icon-small_rz5pc","color-bullet":"components_color_bullet_new_color-bullet_b1w8U","mini":"components_color_bullet_new_mini_B261Z","is-not-library-color":"components_color_bullet_new_is-not-library-color_PSveA","color-bullet-wrapper":"components_color_bullet_new_color-bullet-wrapper_clt4r","is-gradient":"components_color_bullet_new_is-gradient_6RdV2","is-transparent":"components_color_bullet_new_is-transparent_g0iwn","color-text":"components_color_bullet_new_color-text_HM6mp","small-text":"components_color_bullet_new_small-text_Y4OeK","no-text":"components_color_bullet_new_no-text_pbTQf"}
|
||||
{"button-primary":"components_color_bullet_new_button-primary_pDkQg","button-secondary":"components_color_bullet_new_button-secondary_y3A8V","button-tertiary":"components_color_bullet_new_button-tertiary_zPQ8t","button-tag":"components_color_bullet_new_button-tag_2Ur4i","button-icon":"components_color_bullet_new_button-icon_uAC1e","button-icon-small":"components_color_bullet_new_button-icon-small_rz5pc","asset-element":"components_color_bullet_new_asset-element_s3Yqx","color-bullet":"components_color_bullet_new_color-bullet_b1w8U","mini":"components_color_bullet_new_mini_B261Z","is-not-library-color":"components_color_bullet_new_is-not-library-color_PSveA","color-bullet-wrapper":"components_color_bullet_new_color-bullet-wrapper_clt4r","is-gradient":"components_color_bullet_new_is-gradient_6RdV2","is-transparent":"components_color_bullet_new_is-transparent_g0iwn","color-text":"components_color_bullet_new_color-text_HM6mp","small-text":"components_color_bullet_new_small-text_Y4OeK","no-text":"components_color_bullet_new_no-text_pbTQf"}
|
|
@ -10,12 +10,15 @@
|
|||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: var(--bullet-size);
|
||||
height: var(--bullet-size);
|
||||
width: var(--bullet-size, $s-24);
|
||||
height: var(--bullet-size, $s-24);
|
||||
margin-top: $s-4;
|
||||
border: $s-2 solid var(--color-bullet-border-color);
|
||||
border-radius: $br-circle;
|
||||
&.mini {
|
||||
width: var(--bullet-size, $s-16);
|
||||
height: var(--bullet-size, $s-16);
|
||||
margin-top: 0;
|
||||
border: 1px solid var(--color-bullet-border-color);
|
||||
}
|
||||
|
||||
|
|
|
@ -258,6 +258,7 @@
|
|||
:key id
|
||||
:class (if (and new-css-system workspace?)
|
||||
(dom/classnames (css :is-selected) (and selected (= option-name selected))
|
||||
(css :selected) (and selected (= data-test selected))
|
||||
(css :context-menu-item) true)
|
||||
(dom/classnames :is-selected (and selected (= option-name selected))))
|
||||
:key-index (dm/str "context-item-" index)
|
||||
|
@ -274,7 +275,11 @@
|
|||
:data-test data-test}
|
||||
(if (and in-dashboard? (= option-name "Default"))
|
||||
(tr "dashboard.default-team-name")
|
||||
option-name)]
|
||||
option-name)
|
||||
|
||||
(when (and new-css-system selected (= data-test selected))
|
||||
[:span {:class (dom/classnames (css :selected-icon) true)}
|
||||
i/tick-refactor])]
|
||||
[:a {:class (if (and new-css-system workspace?)
|
||||
(dom/classnames (css :context-menu-action) true
|
||||
(css :submenu) true)
|
||||
|
@ -289,7 +294,6 @@
|
|||
i/arrow-refactor
|
||||
i/arrow-slide)]])]))))])])])))
|
||||
|
||||
|
||||
(mf/defc context-menu-a11y
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"button-primary":"components_context_menu_a11y_button-primary_FTrG6","button-secondary":"components_context_menu_a11y_button-secondary_tIeiM","button-icon":"components_context_menu_a11y_button-icon_eOLGl","button-icon-small":"components_context_menu_a11y_button-icon-small_bQvvB","context-menu":"components_context_menu_a11y_context-menu_bS2vM","context-menu-items":"components_context_menu_a11y_context-menu-items_lQC7H","context-menu-item":"components_context_menu_a11y_context-menu-item_E2GpJ","context-menu-action":"components_context_menu_a11y_context-menu-action_E53yg","submenu-back":"components_context_menu_a11y_submenu-back_AboXg","submenu-icon-back":"components_context_menu_a11y_submenu-icon-back_gy-B6","submenu":"components_context_menu_a11y_submenu_MuyM8","submenu-icon":"components_context_menu_a11y_submenu-icon_tWTVU","is-open":"components_context_menu_a11y_is-open_FbqIp","fixed":"components_context_menu_a11y_fixed_iJxPr","separator":"components_context_menu_a11y_separator_DrZoB","min-width":"components_context_menu_a11y_min-width_w-ron","is-selected":"components_context_menu_a11y_is-selected_UPMXx","is-selectable":"components_context_menu_a11y_is-selectable_n7sdb"}
|
||||
{"button-primary":"components_context_menu_a11y_button-primary_FTrG6","button-secondary":"components_context_menu_a11y_button-secondary_tIeiM","button-tertiary":"components_context_menu_a11y_button-tertiary_0A2mW","button-tag":"components_context_menu_a11y_button-tag_iLpM-","context-menu":"components_context_menu_a11y_context-menu_bS2vM","context-menu-items":"components_context_menu_a11y_context-menu-items_lQC7H","context-menu-item":"components_context_menu_a11y_context-menu-item_E2GpJ","selected":"components_context_menu_a11y_selected_on-en","selected-icon":"components_context_menu_a11y_selected-icon_H2S7W","button-icon":"components_context_menu_a11y_button-icon_eOLGl","button-icon-small":"components_context_menu_a11y_button-icon-small_bQvvB","context-menu-action":"components_context_menu_a11y_context-menu-action_E53yg","submenu-back":"components_context_menu_a11y_submenu-back_AboXg","submenu-icon-back":"components_context_menu_a11y_submenu-icon-back_gy-B6","submenu":"components_context_menu_a11y_submenu_MuyM8","submenu-icon":"components_context_menu_a11y_submenu-icon_tWTVU","asset-element":"components_context_menu_a11y_asset-element_r3q1-","is-open":"components_context_menu_a11y_is-open_FbqIp","fixed":"components_context_menu_a11y_fixed_iJxPr","separator":"components_context_menu_a11y_separator_DrZoB","min-width":"components_context_menu_a11y_min-width_w-ron","is-selected":"components_context_menu_a11y_is-selected_UPMXx","is-selectable":"components_context_menu_a11y_is-selectable_n7sdb"}
|
|
@ -109,6 +109,21 @@
|
|||
}
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
.context-menu-action {
|
||||
justify-content: space-between;
|
||||
color: var(--menu-foreground-color-focus);
|
||||
}
|
||||
.selected-icon {
|
||||
@extend .button-tag;
|
||||
border-radius: $br-8;
|
||||
height: 100%;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--menu-foreground-color-focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.is-selected .context-menu-action {
|
||||
padding-left: $s-28;
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
(ns app.main.ui.components.editable-label
|
||||
(:require
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
|
@ -18,6 +19,7 @@
|
|||
tooltip (get props :tooltip)
|
||||
input (mf/use-ref nil)
|
||||
state (mf/use-state (:editing false))
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
is-editing (:editing @state)
|
||||
start-editing (fn []
|
||||
(swap! state assoc :editing true)
|
||||
|
@ -52,7 +54,11 @@
|
|||
:default-value value
|
||||
:on-key-up on-key-up
|
||||
:on-blur cancel-editing}]
|
||||
[:span.editable-label-close {:on-click cancel-editing} i/close]]
|
||||
|
||||
[:span.editable-label-close {:on-click cancel-editing}
|
||||
(if new-css-system
|
||||
i/delete-text-refactor
|
||||
i/close)]]
|
||||
[:span.editable-label {:class class-name
|
||||
:title tooltip
|
||||
:on-double-click on-dbl-click} display-value])))
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"components_editable_label_button-primary_fp-ma","button-secondary":"components_editable_label_button-secondary_QPaT-","button-tertiary":"components_editable_label_button-tertiary_wOORv","button-tag":"components_editable_label_button-tag_pwEqY","button-icon":"components_editable_label_button-icon_acX7H","button-icon-small":"components_editable_label_button-icon-small_tSz5O","asset-element":"components_editable_label_asset-element_Bs5bh","editable-label-input":"components_editable_label_editable-label-input_q2Puk"}
|
21
frontend/src/app/main/ui/components/editable_label.scss
Normal file
|
@ -0,0 +1,21 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.editable-label-input {
|
||||
@include textEllipsis;
|
||||
@include titleTipography;
|
||||
@include removeInputStyle;
|
||||
flex-grow: 1;
|
||||
height: $s-28;
|
||||
max-width: calc(var(--parent-size) - (var(--depth) * var(--layer-indentation-size)));
|
||||
margin: 0;
|
||||
padding-left: $s-6;
|
||||
border-radius: $br-8;
|
||||
border: $s-1 solid var(--input-border-color-focus);
|
||||
color: var(--layer-row-foreground-color);
|
||||
}
|
|
@ -35,6 +35,7 @@
|
|||
default-val (obj/get props "default")
|
||||
nillable (obj/get props "nillable")
|
||||
select-on-focus? (obj/get props "data-select-on-focus" true)
|
||||
class (obj/get props "klass")
|
||||
|
||||
;; We need a ref pointing to the input dom element, but the user
|
||||
;; of this component may provide one (that is forwarded here).
|
||||
|
@ -218,7 +219,7 @@
|
|||
|
||||
props (-> props
|
||||
(obj/without ["value" "onChange" "nillable" "onFocus"])
|
||||
(obj/set! "className" "input-text")
|
||||
(obj/set! "className" (or class "input-text"))
|
||||
(obj/set! "type" "text")
|
||||
(obj/set! "ref" ref)
|
||||
(obj/set! "defaultValue" (fmt/format-number value))
|
||||
|
|
78
frontend/src/app/main/ui/components/radio_buttons.cljs
Normal file
|
@ -0,0 +1,78 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.components.radio-buttons
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.math :as math]
|
||||
[app.main.ui.formats :as fmt]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def ctx-radio-button (mf/create-context nil))
|
||||
|
||||
(mf/defc radio-button
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [ctx (mf/use-ctx ctx-radio-button)
|
||||
icon (unchecked-get props "icon")
|
||||
id (unchecked-get props "id")
|
||||
on-change (:on-change ctx)
|
||||
selected (:selected ctx)
|
||||
value (unchecked-get props "value")
|
||||
checked? (= selected value)
|
||||
name (:name ctx)]
|
||||
[:label {:for id
|
||||
:class (dom/classnames (css :radio-icon) true
|
||||
(css :checked) checked?)}
|
||||
icon
|
||||
[:input {:id id
|
||||
:on-change on-change
|
||||
:type "radio"
|
||||
:name name
|
||||
:value value
|
||||
:checked checked?}]]))
|
||||
|
||||
(mf/defc nilable-option
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [ctx (mf/use-ctx ctx-radio-button)
|
||||
icon (unchecked-get props "icon")
|
||||
id (unchecked-get props "id")
|
||||
on-change (:on-change ctx)
|
||||
selected (:selected ctx)
|
||||
value (unchecked-get props "value")
|
||||
checked? (= selected value)
|
||||
name (:name ctx)]
|
||||
[:label {:for id
|
||||
:class (dom/classnames (css :radio-icon) true
|
||||
(css :checked) checked?)}
|
||||
icon
|
||||
[:input {:id id
|
||||
:on-change on-change
|
||||
:type "checkbox"
|
||||
:name name
|
||||
:value value
|
||||
:checked checked?}]]))
|
||||
|
||||
(mf/defc radio-buttons
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [children (unchecked-get props "children")
|
||||
on-change (unchecked-get props "on-change")
|
||||
selected (unchecked-get props "selected")
|
||||
name (unchecked-get props "name")
|
||||
calculate-width (fmt/format-pixels (+ (math/pow 2 (count children)) (* 28 (count children))))
|
||||
handle-change
|
||||
(mf/use-fn
|
||||
(mf/deps on-change)
|
||||
(fn [event]
|
||||
(let [value (dom/get-target-val event)]
|
||||
(on-change value event))))]
|
||||
[:& (mf/provider ctx-radio-button) {:value {:selected selected :on-change handle-change :name name}}
|
||||
[:div {:class (css :radio-btn-wrapper)
|
||||
:style {:width calculate-width}}
|
||||
children]]))
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"components_radio_buttons_button-primary_-XZNO","button-secondary":"components_radio_buttons_button-secondary_yj3Oe","button-tertiary":"components_radio_buttons_button-tertiary_s2RvI","radio-icon":"components_radio_buttons_radio-icon_1OnG1","button-tag":"components_radio_buttons_button-tag_4VTp-","button-icon":"components_radio_buttons_button-icon_jP0XC","button-icon-small":"components_radio_buttons_button-icon-small_3AO-R","asset-element":"components_radio_buttons_asset-element_l2wMX","radio-btn-wrapper":"components_radio_buttons_radio-btn-wrapper_mH6QX","checked":"components_radio_buttons_checked_sjVzy"}
|
42
frontend/src/app/main/ui/components/radio_buttons.scss
Normal file
|
@ -0,0 +1,42 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.radio-btn-wrapper {
|
||||
@include flexCenter;
|
||||
border-radius: $br-8;
|
||||
height: $s-32;
|
||||
background-color: var(--radio-btns-background-color);
|
||||
}
|
||||
.radio-icon {
|
||||
@extend .button-tertiary;
|
||||
height: $s-28;
|
||||
width: 100%;
|
||||
border-radius: $s-6;
|
||||
border: solid $s-2 transparent;
|
||||
box-sizing: content-box;
|
||||
input {
|
||||
display: none;
|
||||
}
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
stroke: var(--radio-btn-foreground-color);
|
||||
}
|
||||
&:hover {
|
||||
border: solid $s-2 var(--radio-btns-background-color);
|
||||
}
|
||||
&.checked {
|
||||
background-color: var(--radio-btn-background-color-selected);
|
||||
border: $s-2 solid var(--radio-btn-border-color-selected);
|
||||
svg {
|
||||
stroke: var(--radio-btn-foreground-color-selected);
|
||||
}
|
||||
&:hover {
|
||||
border: $s-2 solid var(--radio-btn-border-color-selected);
|
||||
}
|
||||
}
|
||||
}
|
60
frontend/src/app/main/ui/components/search_bar.cljs
Normal file
|
@ -0,0 +1,60 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.components.search-bar
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc search-bar
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [children (unchecked-get props "children")
|
||||
on-change (unchecked-get props "on-change")
|
||||
value (unchecked-get props "value")
|
||||
on-clear (unchecked-get props "clear-action")
|
||||
placeholder (unchecked-get props "placeholder")
|
||||
icon (unchecked-get props "icon")
|
||||
|
||||
handle-change
|
||||
(mf/use-fn
|
||||
(mf/deps on-change)
|
||||
(fn [event]
|
||||
(let [value (dom/get-target-val event)]
|
||||
(on-change value event))))
|
||||
|
||||
handle-clear
|
||||
(mf/use-fn
|
||||
(mf/deps on-clear on-change)
|
||||
(fn [event]
|
||||
(if on-clear
|
||||
(on-clear event)
|
||||
(on-change "" event))))
|
||||
|
||||
handle-key-down
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [enter? (kbd/enter? event)
|
||||
esc? (kbd/esc? event)
|
||||
node (dom/event->target event)]
|
||||
(when ^boolean enter? (dom/blur! node))
|
||||
(when ^boolean esc? (dom/blur! node)))))]
|
||||
[:span {:class (dom/classnames (css :search-box) true
|
||||
(css :has-children) (some? children))}
|
||||
children
|
||||
[:div {:class (dom/classnames (css :search-input-wrapper) true)}
|
||||
icon
|
||||
[:input {:on-change handle-change
|
||||
:value value
|
||||
:placeholder placeholder
|
||||
:on-key-down handle-key-down}]
|
||||
(when (not= "" value)
|
||||
[:button {:class (dom/classnames (css :clear) true)
|
||||
:on-click handle-clear}
|
||||
i/delete-text-refactor])]]))
|
1
frontend/src/app/main/ui/components/search_bar.css.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"button-primary":"components_search_bar_button-primary_-9D1J","button-secondary":"components_search_bar_button-secondary_GbDgI","button-tertiary":"components_search_bar_button-tertiary_VTCfX","button-tag":"components_search_bar_button-tag_dKink","search-box":"components_search_bar_search-box_AFEzz","search-input-wrapper":"components_search_bar_search-input-wrapper_Djsml","clear":"components_search_bar_clear_B6lfz","button-icon":"components_search_bar_button-icon_CdwNa","button-icon-small":"components_search_bar_button-icon-small_gSOsT","asset-element":"components_search_bar_asset-element_rH-5k","has-children":"components_search_bar_has-children_u-VSq"}
|
66
frontend/src/app/main/ui/components/search_bar.scss
Normal file
|
@ -0,0 +1,66 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.search-box {
|
||||
display: flex;
|
||||
gap: $s-2;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--search-bar-background-color);
|
||||
|
||||
.search-input-wrapper {
|
||||
@include flexCenter;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
border: $s-1 solid var(--search-bar-input-border-color);
|
||||
border-radius: $br-8;
|
||||
background-color: var(--search-bar-input-background-color);
|
||||
input {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0 $s-8 0 $s-4;
|
||||
border: 0;
|
||||
background-color: var(--input-background-color);
|
||||
font-size: $fs-12;
|
||||
color: var(--input-foreground-color);
|
||||
&:focus {
|
||||
outline: none;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
border: $s-1 solid var(--input-background-color-hover);
|
||||
background-color: var(--input-background-color-hover);
|
||||
input {
|
||||
background-color: var(--input-background-color-hover);
|
||||
}
|
||||
}
|
||||
&:focus-within {
|
||||
background-color: var(--input-background-color-active);
|
||||
color: var(--input-foreground-color-active);
|
||||
border: $s-1 solid var(--input-border-color-focus);
|
||||
input {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
}
|
||||
|
||||
.clear {
|
||||
@extend .button-tag;
|
||||
border-radius: $br-8;
|
||||
height: 100%;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
color: transparent;
|
||||
}
|
||||
}
|
||||
}
|
||||
&.has-children .search-input-wrapper {
|
||||
border-radius: $br-2 $br-8 $br-8 $br-2;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
|
@ -5,11 +5,13 @@
|
|||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.components.select
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.uuid :as uuid]
|
||||
[app.main.ui.components.dropdown :refer [dropdown]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
@ -22,7 +24,8 @@
|
|||
|
||||
(mf/defc select
|
||||
[{:keys [default-value options class is-open? on-change on-pointer-enter-option on-pointer-leave-option]}]
|
||||
(let [label-index (mf/with-memo [options]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
label-index (mf/with-memo [options]
|
||||
(into {} (map as-key-value) options))
|
||||
|
||||
state* (mf/use-state
|
||||
|
@ -73,22 +76,46 @@
|
|||
|
||||
(mf/with-effect [default-value]
|
||||
(swap! state* assoc :current-value default-value))
|
||||
(if new-css-system
|
||||
[:div {:on-click open-dropdown :class (dom/classnames (css class) true
|
||||
(css :custom-select) true)}
|
||||
[:span {:class (css :current-label)} current-label]
|
||||
[:span {:class (css :dropdown-button)} i/arrow-refactor]
|
||||
[:& dropdown {:show is-open? :on-close close-dropdown}
|
||||
[:ul {:class (css :custom-select-dropdown)}
|
||||
(for [[index item] (d/enumerate options)]
|
||||
(if (= :separator item)
|
||||
[:hr {:key (dm/str current-id "-" index)}]
|
||||
(let [[value label] (as-key-value item)]
|
||||
[:li
|
||||
{:key (dm/str current-id "-" index)
|
||||
:class (dom/classnames
|
||||
(css :checked-element) true
|
||||
(css :is-selected) (= value current-value))
|
||||
:data-value (pr-str value)
|
||||
:on-pointer-enter highlight-item
|
||||
:on-pointer-leave unhighlight-item
|
||||
:on-click select-item}
|
||||
[:span {:class (css :label)} label]
|
||||
[:span {:class (css :check-icon)} i/tick-refactor]])))]]]
|
||||
|
||||
|
||||
|
||||
[:div.custom-select {:on-click open-dropdown :class class}
|
||||
[:span current-label]
|
||||
[:span.dropdown-button i/arrow-down]
|
||||
[:& dropdown {:show is-open? :on-close close-dropdown}
|
||||
[:ul.custom-select-dropdown
|
||||
(for [[index item] (d/enumerate options)]
|
||||
(if (= :separator item)
|
||||
[:hr {:key (dm/str current-id "-" index)}]
|
||||
(let [[value label] (as-key-value item)]
|
||||
[:li.checked-element
|
||||
{:key (dm/str current-id "-" index)
|
||||
:class (when (= value current-value) "is-selected")
|
||||
:data-value (pr-str value)
|
||||
:on-pointer-enter highlight-item
|
||||
:on-pointer-leave unhighlight-item
|
||||
:on-click select-item}
|
||||
[:span.check-icon i/tick]
|
||||
[:span label]])))]]]))
|
||||
[:div.custom-select {:on-click open-dropdown :class class}
|
||||
[:span current-label]
|
||||
[:span.dropdown-button i/arrow-down]
|
||||
[:& dropdown {:show is-open? :on-close close-dropdown}
|
||||
[:ul.custom-select-dropdown
|
||||
(for [[index item] (d/enumerate options)]
|
||||
(if (= :separator item)
|
||||
[:hr {:key (dm/str current-id "-" index)}]
|
||||
(let [[value label] (as-key-value item)]
|
||||
[:li.checked-element
|
||||
{:key (dm/str current-id "-" index)
|
||||
:class (when (= value current-value) "is-selected")
|
||||
:data-value (pr-str value)
|
||||
:on-pointer-enter highlight-item
|
||||
:on-pointer-leave unhighlight-item
|
||||
:on-click select-item}
|
||||
[:span.check-icon i/tick]
|
||||
[:span label]])))]]])))
|
||||
|
|
1
frontend/src/app/main/ui/components/select.css.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"button-primary":"components_select_button-primary_peYzv","button-secondary":"components_select_button-secondary_Kse6w","button-tertiary":"components_select_button-tertiary_srwoV","button-tag":"components_select_button-tag_AJXtX","button-icon":"components_select_button-icon_86LWm","custom-select":"components_select_custom-select_OM8-6","dropdown-button":"components_select_dropdown-button_IcpuR","button-icon-small":"components_select_button-icon-small_H0Bue","checked-element":"components_select_checked-element_c5-i4","check-icon":"components_select_check-icon_9x082","asset-element":"components_select_asset-element_5vxj7","current-label":"components_select_current-label_CUaQs","custom-select-dropdown":"components_select_custom-select-dropdown_2yZj9","label":"components_select_label_kTY8t","is-selected":"components_select_is-selected_nTUGr"}
|
84
frontend/src/app/main/ui/components/select.scss
Normal file
|
@ -0,0 +1,84 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.custom-select {
|
||||
position: relative;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: $s-8;
|
||||
border-radius: $br-8;
|
||||
cursor: pointer;
|
||||
.current-label {
|
||||
width: 100%;
|
||||
flex-grow: 1;
|
||||
}
|
||||
.dropdown-button {
|
||||
@include flexCenter;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
.custom-select-dropdown {
|
||||
position: absolute;
|
||||
top: $s-32;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
padding: $s-2;
|
||||
margin: 0;
|
||||
margin-top: $s-4;
|
||||
border-radius: $br-8;
|
||||
z-index: $z-index-10;
|
||||
overflow-y: auto;
|
||||
background-color: var(--menu-background-color);
|
||||
box-shadow: 0px 0px $s-12 0px var(--menu-shadow-color);
|
||||
}
|
||||
.checked-element {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-32;
|
||||
padding: $s-8;
|
||||
border-radius: $br-6;
|
||||
color: var(--menu-foreground-color);
|
||||
.label {
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.check-icon {
|
||||
@include flexCenter;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
visibility: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
.check-icon svg {
|
||||
stroke: var(--menu-foreground-color);
|
||||
visibility: visible;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--menu-background-color-hover);
|
||||
color: var(--menu-foreground-color-hover);
|
||||
.check-icon svg {
|
||||
stroke: var(--menu-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
.dropdown-button {
|
||||
color: var(--menu-foreground-color-hover);
|
||||
svg {
|
||||
stroke: var(--menu-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -35,10 +35,10 @@
|
|||
on-change (unchecked-get props "on-change-tab")
|
||||
collapsable? (unchecked-get props "collapsable?")
|
||||
handle-collapse (unchecked-get props "handle-collapse")
|
||||
klass (unchecked-get props "klass")
|
||||
|
||||
state (mf/use-state #(or selected (-> children first .-props .-id)))
|
||||
selected (or selected @state)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
select-fn
|
||||
(mf/use-fn
|
||||
|
@ -48,42 +48,26 @@
|
|||
(reset! state id)
|
||||
(when (fn? on-change) (on-change id)))))]
|
||||
|
||||
[:div {:class (if new-css-system
|
||||
(dom/classnames (css :tab-container) true)
|
||||
(dom/classnames :tab-container true))}
|
||||
[:div {:class (if new-css-system
|
||||
(dom/classnames (css :tab-container-tabs) true)
|
||||
(dom/classnames :tab-container-tabs true))}
|
||||
(when (and new-css-system collapsable?)
|
||||
[:div {:class (dom/classnames (css :tab-container) true)}
|
||||
[:div {:class (dom/classnames (css :tab-container-tabs) true
|
||||
klass true)}
|
||||
(when collapsable?
|
||||
[:button
|
||||
{:on-click handle-collapse
|
||||
:class (dom/classnames (css :collapse-sidebar) true)
|
||||
:aria-label (tr "workspace.sidebar.collapse")}
|
||||
i/arrow-refactor])
|
||||
(if new-css-system
|
||||
[:div {:class (dom/classnames (css :tab-container-tab-wrapper) new-css-system)}
|
||||
(for [tab children]
|
||||
(let [props (.-props tab)
|
||||
id (.-id props)
|
||||
title (.-title props)]
|
||||
[:div
|
||||
{:key (str/concat "tab-" (d/name id))
|
||||
:data-id (pr-str id)
|
||||
:on-click select-fn
|
||||
:class (dom/classnames (css :tab-container-tab-title) true
|
||||
(css :current) (= selected id))}
|
||||
title]))]
|
||||
(for [tab children]
|
||||
(let [props (.-props tab)
|
||||
id (.-id props)
|
||||
title (.-title props)]
|
||||
[:div.tab-container-tab-title
|
||||
{:key (str/concat "tab-" (d/name id))
|
||||
:data-id (pr-str id)
|
||||
:on-click select-fn
|
||||
:class (when (= selected id) "current")}
|
||||
title])))]
|
||||
[:div {:class (if new-css-system
|
||||
(dom/classnames (css :tab-container-content) true)
|
||||
(dom/classnames :tab-container-content true))}
|
||||
[:div {:class (dom/classnames (css :tab-container-tab-wrapper) true)}
|
||||
(for [tab children]
|
||||
(let [props (.-props tab)
|
||||
id (.-id props)
|
||||
title (.-title props)]
|
||||
[:div
|
||||
{:key (str/concat "tab-" (d/name id))
|
||||
:data-id (pr-str id)
|
||||
:on-click select-fn
|
||||
:class (dom/classnames (css :tab-container-tab-title) true
|
||||
(css :current) (= selected id))}
|
||||
title]))]]
|
||||
[:div {:class (dom/classnames (css :tab-container-content) true)}
|
||||
(d/seek #(= selected (-> % .-props .-id)) children)]]))
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"button-primary":"components_tab_container_button-primary_ibiAz","button-secondary":"components_tab_container_button-secondary_wZR80","button-icon":"components_tab_container_button-icon_2NhVr","button-icon-small":"components_tab_container_button-icon-small_yU7na","tab-container":"components_tab_container_tab-container_P6HRr","tab-container-content":"components_tab_container_tab-container-content_yfM9F","tab-element":"components_tab_container_tab-element_gBIwV","tab-container-tabs":"components_tab_container_tab-container-tabs_6gXOY","tab-container-tab-wrapper":"components_tab_container_tab-container-tab-wrapper_-ngrN","tab-container-tab-title":"components_tab_container_tab-container-tab-title_IN1Dx","current":"components_tab_container_current_jrovp","collapse-sidebar":"components_tab_container_collapse-sidebar_e5hFv","collapsed":"components_tab_container_collapsed_lfkjK"}
|
||||
{"button-primary":"components_tab_container_button-primary_ibiAz","button-secondary":"components_tab_container_button-secondary_wZR80","button-tertiary":"components_tab_container_button-tertiary_JHJAx","button-tag":"components_tab_container_button-tag_NnL8y","button-icon":"components_tab_container_button-icon_2NhVr","button-icon-small":"components_tab_container_button-icon-small_yU7na","asset-element":"components_tab_container_asset-element_1-YWa","tab-container":"components_tab_container_tab-container_P6HRr","tab-container-content":"components_tab_container_tab-container-content_yfM9F","tab-element":"components_tab_container_tab-element_gBIwV","tab-container-tabs":"components_tab_container_tab-container-tabs_6gXOY","tab-container-tab-wrapper":"components_tab_container_tab-container-tab-wrapper_-ngrN","tab-container-tab-title":"components_tab_container_tab-container-tab-title_IN1Dx","current":"components_tab_container_current_jrovp","collapse-sidebar":"components_tab_container_collapse-sidebar_e5hFv","collapsed":"components_tab_container_collapsed_lfkjK"}
|
|
@ -26,8 +26,7 @@
|
|||
flex-direction: row;
|
||||
gap: $s-2;
|
||||
height: $s-32;
|
||||
margin: $s-4 $s-4 0 $s-4;
|
||||
padding: $s-2 $s-2 $s-2 0;
|
||||
padding: $s-2 $s-2 $s-2 $s-2;
|
||||
border-radius: $br-8;
|
||||
background: var(--color-background-secondary);
|
||||
cursor: pointer;
|
||||
|
@ -43,10 +42,12 @@
|
|||
@include tabTitleTipography;
|
||||
height: $s-28;
|
||||
width: 100%;
|
||||
padding: 0 $s-8;
|
||||
margin: 0;
|
||||
border-radius: $br-5;
|
||||
background-color: transparent;
|
||||
color: var(--tab-foreground-color);
|
||||
white-space: nowrap;
|
||||
|
||||
&.current,
|
||||
&.current:hover {
|
||||
|
@ -63,12 +64,13 @@
|
|||
@include buttonStyle;
|
||||
height: 100%;
|
||||
width: $s-24;
|
||||
padding: 0;
|
||||
min-width: $s-24;
|
||||
padding: 0 $s-6 0 0;
|
||||
border-radius: $br-5;
|
||||
svg {
|
||||
@include flexCenter;
|
||||
height: 12px;
|
||||
width: 16px;
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
stroke: var(--icon-foreground);
|
||||
transform: rotate(180deg);
|
||||
fill: none;
|
||||
|
@ -83,6 +85,7 @@
|
|||
&.collapsed {
|
||||
svg {
|
||||
transform: rotate(0deg);
|
||||
padding: 0 0 0 $s-6;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
42
frontend/src/app/main/ui/components/title_bar.cljs
Normal file
|
@ -0,0 +1,42 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.components.title-bar
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc title-bar
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [collapsable? (unchecked-get props "collapsable?")
|
||||
collapsed? (unchecked-get props "collapsed?")
|
||||
on-collapsed (unchecked-get props "on-collapsed")
|
||||
title (unchecked-get props "title")
|
||||
children (unchecked-get props "children")
|
||||
on-btn-click (unchecked-get props "on-btn-click")
|
||||
btn-children (unchecked-get props "btn-children")
|
||||
klass (unchecked-get props "klass")]
|
||||
|
||||
[:div {:class (dom/classnames (css :title-bar) true
|
||||
klass true)}
|
||||
(if collapsable?
|
||||
[:button {:class (dom/classnames (css :toggle-btn) true)
|
||||
:on-click on-collapsed}
|
||||
[:span {:class (dom/classnames (css :collased-icon) true
|
||||
(css :rotated) collapsed?)}
|
||||
i/arrow-refactor]
|
||||
[:div {:class (dom/classnames (css :title) true)}
|
||||
title]]
|
||||
[:div {:class (dom/classnames (css :title-only) true)}
|
||||
title])
|
||||
children
|
||||
(when (some? on-btn-click)
|
||||
[:button {:class (dom/classnames (css :title-button) true)
|
||||
:on-click on-btn-click}
|
||||
btn-children])]))
|
1
frontend/src/app/main/ui/components/title_bar.css.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"button-primary":"components_title_bar_button-primary_svLtU","button-secondary":"components_title_bar_button-secondary_JA5NP","button-tertiary":"components_title_bar_button-tertiary_yqQfO","title-bar":"components_title_bar_title-bar_oUkS0","title-button":"components_title_bar_title-button_xTE-7","button-tag":"components_title_bar_button-tag_o9yFT","button-icon":"components_title_bar_button-icon_ROHrz","button-icon-small":"components_title_bar_button-icon-small_WibJp","toggle-btn":"components_title_bar_toggle-btn_9ekUv","collased-icon":"components_title_bar_collased-icon_SJ1ls","asset-element":"components_title_bar_asset-element_64u6f","title":"components_title_bar_title_qPuju","title-only":"components_title_bar_title-only_aSsdC","rotated":"components_title_bar_rotated_9z7Rn"}
|
78
frontend/src/app/main/ui/components/title_bar.scss
Normal file
|
@ -0,0 +1,78 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.title-bar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
min-height: $s-32;
|
||||
background-color: var(--title-background-color);
|
||||
.title,
|
||||
.title-only {
|
||||
@include tabTitleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
height: 100%;
|
||||
min-height: $s-32;
|
||||
margin-right: $s-8;
|
||||
color: var(--title-foreground-color);
|
||||
}
|
||||
.title-only {
|
||||
margin-left: $s-8;
|
||||
}
|
||||
|
||||
.toggle-btn {
|
||||
@include buttonStyle;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
gap: $s-4;
|
||||
padding: 0;
|
||||
color: var(--title-foreground-color);
|
||||
stroke: var(--title-foreground-color);
|
||||
.collased-icon {
|
||||
@include flexCenter;
|
||||
height: $s-24;
|
||||
width: $s-24;
|
||||
border-radius: $br-8;
|
||||
padding: 0 $s-4 0 $s-8;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
&.rotated svg {
|
||||
transform: rotate(0deg);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
color: var(--title-foreground-color-hover);
|
||||
stroke: var(--title-foreground-color-hover);
|
||||
.title {
|
||||
color: var(--title-foreground-color-hover);
|
||||
stroke: var(--title-foreground-color-hover);
|
||||
}
|
||||
.collased-icon svg {
|
||||
stroke: var(--title-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title-button {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: calc($s-24 + $s-4);
|
||||
padding: 0;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -10,9 +10,23 @@
|
|||
[app.main.data.users :as du]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
|
||||
[app.main.ui.components.search-bar :refer [search-bar]]
|
||||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc component-wrapper
|
||||
{::mf/wrap-props false}
|
||||
[props]
|
||||
(let [children (unchecked-get props "children")
|
||||
title (unchecked-get props "title")]
|
||||
[:div {:class (dom/classnames (css :component) true)}
|
||||
[:h4 {:class (dom/classnames (css :component-name) true)} title]
|
||||
children]))
|
||||
|
||||
(mf/defc components-preview
|
||||
{::mf/wrap-props false}
|
||||
[]
|
||||
|
@ -24,7 +38,6 @@
|
|||
(let [theme (dom/event->value event)
|
||||
data (assoc initial :theme theme)]
|
||||
(st/emit! (du/update-profile data))))
|
||||
|
||||
colors [:bg-primary
|
||||
:bg-secondary
|
||||
:bg-tertiary
|
||||
|
@ -34,10 +47,37 @@
|
|||
:acc
|
||||
:acc-muted
|
||||
:acc-secondary
|
||||
:acc-tertiary]]
|
||||
:acc-tertiary]
|
||||
|
||||
;; COMPONENTS FNs
|
||||
state* (mf/use-state {:collapsed? true
|
||||
:tab-selected :first
|
||||
:input-value ""
|
||||
:radio-selected "first"})
|
||||
state (deref state*)
|
||||
|
||||
collapsed? (:collapsed? state)
|
||||
toggle-collapsed
|
||||
(mf/use-fn #(swap! state* update :collapsed? not))
|
||||
|
||||
tab-selected (:tab-selected state)
|
||||
set-tab (mf/use-fn #(swap! state* assoc :tab-selected %))
|
||||
|
||||
input-value (:input-value state)
|
||||
radio-selected (:radio-selected state)
|
||||
|
||||
set-radio-selected (mf/use-fn #(swap! state* assoc :radio-selected %))
|
||||
|
||||
update-search
|
||||
(mf/use-fn
|
||||
(fn [value _event]
|
||||
(swap! state* assoc :input-value value)))
|
||||
|
||||
|
||||
on-btn-click (mf/use-fn #(prn "eyy"))]
|
||||
|
||||
[:section.debug-components-preview
|
||||
[:div {:class (css :themes-row)}
|
||||
[:div {:class (dom/classnames (css :themes-row) true)}
|
||||
[:h2 "Themes"]
|
||||
[:select {:label "Select theme color"
|
||||
:name :theme
|
||||
|
@ -46,12 +86,135 @@
|
|||
:on-change on-change}
|
||||
[:option {:label "Penpot Dark (default)" :value "default"}]
|
||||
[:option {:label "Penpot Light" :value "light"}]]
|
||||
[:div {:class (css :wrapper)}
|
||||
[:div {:class (dom/classnames (css :wrapper) true)}
|
||||
(let [css (styles)]
|
||||
(for [color colors]
|
||||
[:div {:class (dom/classnames (get css color) true
|
||||
[:div {:key color
|
||||
:class (dom/classnames (get css color) true
|
||||
(get css :rect) true)}
|
||||
(d/name color)]))]]
|
||||
[:div {:class (css :components-row)}
|
||||
[:h2 {:class (css :title)} "Components"]
|
||||
[:div {:class (css :component-wrapper)}]]]))
|
||||
[:div {:class (dom/classnames (css :components-row) true)}
|
||||
[:h2 {:class (dom/classnames (css :title) true)} "Components"]
|
||||
[:div {:class (dom/classnames (css :components-wrapper) true)}
|
||||
[:div {:class (dom/classnames (css :component-group) true)}
|
||||
[:h3 "Titles"]
|
||||
[:& component-wrapper
|
||||
{:title "Title"}
|
||||
[:& title-bar {:collapsable? false
|
||||
:title "Title"}]]
|
||||
[:& component-wrapper
|
||||
{:title "Title and action button"}
|
||||
[:& title-bar {:collapsable? false
|
||||
:title "Title"
|
||||
:on-btn-click on-btn-click
|
||||
:btn-children i/add-refactor}]]
|
||||
[:& component-wrapper
|
||||
{:title "Collapsed title and action button"}
|
||||
[:& title-bar {:collapsable? true
|
||||
:collapsed? collapsed?
|
||||
:on-collapsed toggle-collapsed
|
||||
:title "Title"
|
||||
:on-btn-click on-btn-click
|
||||
:btn-children i/add-refactor}]]
|
||||
[:& component-wrapper
|
||||
{:title "Collapsed title and children"}
|
||||
[:& title-bar {:collapsable? true
|
||||
:collapsed? collapsed?
|
||||
:on-collapsed toggle-collapsed
|
||||
:title "Title"}
|
||||
[:& tab-container {:on-change-tab set-tab
|
||||
:selected tab-selected}
|
||||
[:& tab-element {:id :first
|
||||
:title "A tab"}]
|
||||
[:& tab-element {:id :second
|
||||
:title "B tab"}]]]]]
|
||||
|
||||
[:div {:class (dom/classnames (css :component-group) true)}
|
||||
[:h3 "Tabs component"]
|
||||
[:& component-wrapper
|
||||
{:title "2 tab component"}
|
||||
[:& tab-container {:on-change-tab set-tab
|
||||
:selected tab-selected}
|
||||
[:& tab-element {:id :first :title "First tab"}
|
||||
[:div "This is first tab content"]]
|
||||
|
||||
[:& tab-element {:id :second :title "Second tab"}
|
||||
[:div "This is second tab content"]]]]
|
||||
[:& component-wrapper
|
||||
{:title "3 tab component"}
|
||||
[:& tab-container {:on-change-tab set-tab
|
||||
:selected tab-selected}
|
||||
[:& tab-element {:id :first :title "First tab"}
|
||||
[:div "This is first tab content"]]
|
||||
|
||||
[:& tab-element {:id :second
|
||||
:title "Second tab"}
|
||||
[:div "This is second tab content"]]
|
||||
[:& tab-element {:id :third
|
||||
:title "Third tab"}
|
||||
[:div "This is third tab content"]]]]]
|
||||
|
||||
[:div {:class (dom/classnames (css :component-group) true)}
|
||||
[:h3 "Search bar"]
|
||||
[:& component-wrapper
|
||||
{:title "Search bar only"}
|
||||
[:& search-bar {:on-change update-search
|
||||
:value input-value
|
||||
:placeholder "Test value"}]]
|
||||
[:& component-wrapper
|
||||
{:title "Search and button"}
|
||||
[:& search-bar {:on-change update-search
|
||||
:value input-value
|
||||
:placeholder "Test value"}
|
||||
[:button {:class (dom/classnames (css :test-button) true)
|
||||
:on-click on-btn-click}
|
||||
"X"]]]]
|
||||
|
||||
[:div {:class (dom/classnames (css :component-group) true)}
|
||||
[:h3 "Radio buttons"]
|
||||
[:& component-wrapper
|
||||
{:title "Two radio buttons (toggle)"}
|
||||
[:& radio-buttons {:selected radio-selected
|
||||
:on-change set-radio-selected
|
||||
:name "listing-style"}
|
||||
[:& radio-button {:icon (mf/html i/view-as-list-refactor)
|
||||
:value "first"
|
||||
:id :list}]
|
||||
[:& radio-button {:icon (mf/html i/flex-grid-refactor)
|
||||
:value "second"
|
||||
:id :grid}]]]
|
||||
[:& component-wrapper
|
||||
{:title "Three radio buttons"}
|
||||
[:& radio-buttons {:selected radio-selected
|
||||
:on-change set-radio-selected
|
||||
:name "listing-style"}
|
||||
[:& radio-button {:icon (mf/html i/view-as-list-refactor)
|
||||
:value "first"
|
||||
:id :first}]
|
||||
[:& radio-button {:icon (mf/html i/flex-grid-refactor)
|
||||
:value "second"
|
||||
:id :second}]
|
||||
|
||||
[:& radio-button {:icon (mf/html i/add-refactor)
|
||||
:value "third"
|
||||
:id :third}]]]
|
||||
|
||||
[:& component-wrapper
|
||||
{:title "Four radio buttons"}
|
||||
[:& radio-buttons {:selected radio-selected
|
||||
:on-change set-radio-selected
|
||||
:name "listing-style"}
|
||||
[:& radio-button {:icon (mf/html i/view-as-list-refactor)
|
||||
:value "first"
|
||||
:id :first}]
|
||||
[:& radio-button {:icon (mf/html i/flex-grid-refactor)
|
||||
:value "second"
|
||||
:id :second}]
|
||||
|
||||
[:& radio-button {:icon (mf/html i/add-refactor)
|
||||
:value "third"
|
||||
:id :third}]
|
||||
|
||||
[:& radio-button {:icon (mf/html i/board-refactor)
|
||||
:value "forth"
|
||||
:id :forth}]]]]]]]))
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"button-primary":"debug_components_preview_button-primary_Q2m40","button-secondary":"debug_components_preview_button-secondary_yPp3n","button-icon":"debug_components_preview_button-icon_J36A6","button-icon-small":"debug_components_preview_button-icon-small_Pf3jb","themes-row":"debug_components_preview_themes-row_wEU8d","wrapper":"debug_components_preview_wrapper_535-4","rect":"debug_components_preview_rect_jomnq","bg-primary":"debug_components_preview_bg-primary_Rt4oW","bg-secondary":"debug_components_preview_bg-secondary_rcmll","bg-tertiary":"debug_components_preview_bg-tertiary_7rITE","bg-cuaternary":"debug_components_preview_bg-cuaternary_UEBPN","fg-primary":"debug_components_preview_fg-primary_naliT","fg-secondary":"debug_components_preview_fg-secondary_zT9IX","acc":"debug_components_preview_acc_h3Bia","acc-muted":"debug_components_preview_acc-muted_uingh","acc-secondary":"debug_components_preview_acc-secondary_oHH6y","acc-tertiary":"debug_components_preview_acc-tertiary_SwBjy","components-row":"debug_components_preview_components-row_N3f-J","title":"debug_components_preview_title_TVtzz","component-wrapper":"debug_components_preview_component-wrapper_yC9G1"}
|
||||
{"button-primary":"debug_components_preview_button-primary_Q2m40","button-secondary":"debug_components_preview_button-secondary_yPp3n","button-tertiary":"debug_components_preview_button-tertiary_FIKgJ","button-tag":"debug_components_preview_button-tag_NNepE","button-icon":"debug_components_preview_button-icon_J36A6","button-icon-small":"debug_components_preview_button-icon-small_Pf3jb","asset-element":"debug_components_preview_asset-element_LhcNS","themes-row":"debug_components_preview_themes-row_wEU8d","wrapper":"debug_components_preview_wrapper_535-4","rect":"debug_components_preview_rect_jomnq","bg-primary":"debug_components_preview_bg-primary_Rt4oW","bg-secondary":"debug_components_preview_bg-secondary_rcmll","bg-tertiary":"debug_components_preview_bg-tertiary_7rITE","bg-cuaternary":"debug_components_preview_bg-cuaternary_UEBPN","fg-primary":"debug_components_preview_fg-primary_naliT","fg-secondary":"debug_components_preview_fg-secondary_zT9IX","acc":"debug_components_preview_acc_h3Bia","acc-muted":"debug_components_preview_acc-muted_uingh","acc-secondary":"debug_components_preview_acc-secondary_oHH6y","acc-tertiary":"debug_components_preview_acc-tertiary_SwBjy","components-row":"debug_components_preview_components-row_N3f-J","title":"debug_components_preview_title_TVtzz","components-wrapper":"debug_components_preview_components-wrapper_A8IgV","component-group":"debug_components_preview_component-group_dI55k","component":"debug_components_preview_component_xBMSU","component-name":"debug_components_preview_component-name_3ZJMW"}
|
|
@ -79,7 +79,33 @@
|
|||
.title {
|
||||
padding: $s-20;
|
||||
}
|
||||
.component-wrapper {
|
||||
.components-wrapper {
|
||||
padding: $s-20;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.component-group {
|
||||
@include flexCenter;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
// width: $s-256;
|
||||
border-radius: $s-8;
|
||||
h3 {
|
||||
@include titleTipography;
|
||||
font-size: $fs-25;
|
||||
width: 100%;
|
||||
}
|
||||
.component {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-8;
|
||||
width: $s-240;
|
||||
max-height: $s-80;
|
||||
margin-bottom: $s-16;
|
||||
.component-name {
|
||||
@include tabTitleTipography;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -297,6 +297,7 @@
|
|||
(def distribute-vertical-sapcing-refactor (icon-xref :distribute-vertical-spacing-refactor))
|
||||
(def delete-refactor (icon-xref :delete-refactor))
|
||||
(def delete-text-refactor (icon-xref :delete-text-refactor))
|
||||
(def detach-refactor (icon-xref :detach-refactor))
|
||||
(def document-refactor (icon-xref :document-refactor))
|
||||
(def drop-refactor (icon-xref :drop-refactor))
|
||||
(def effects-refactor (icon-xref :effects-refactor))
|
||||
|
@ -365,9 +366,23 @@
|
|||
(def text-align-right-refactor (icon-xref :text-align-right-refactor))
|
||||
(def text-auto-height-refactor (icon-xref :text-auto-height-refactor))
|
||||
(def text-auto-width-refactor (icon-xref :text-auto-width-refactor))
|
||||
|
||||
(def text-fixed-refactor (icon-xref :textfixed--refactor))
|
||||
(def text-justify-refactor (icon-xref :text-justify-refactor))
|
||||
(def text-letterspacing-refactor (icon-xref :text-letterspacing-refactor))
|
||||
(def text-lineheight-refactor (icon-xref :text-lineheight-refactor))
|
||||
(def text-lowercase-refactor (icon-xref :text-lowercase-refactor))
|
||||
(def text-LTR-refactor (icon-xref :text-LTR-refactor))
|
||||
(def text-middle-refactor (icon-xref :text-middle-refactor))
|
||||
(def text-mixed-refactor (icon-xref :text-mixed-refactor))
|
||||
(def text-palette-refactor (icon-xref :text-palette-refactor))
|
||||
(def text-paragraph-refactor (icon-xref :text-paragraph-refactor))
|
||||
(def text-refactor (icon-xref :text-refactor))
|
||||
(def text-palette-refactor (icon-xref :text-palette-refactor))
|
||||
(def text-RTL-refactor (icon-xref :text-RTL-refactor))
|
||||
(def text-stroked-refactor (icon-xref :text-stroked-refactor))
|
||||
(def text-top-refactor (icon-xref :text-top-refactor))
|
||||
(def text-underlined-refactor (icon-xref :text-underlined-refactor))
|
||||
(def text-uppercase-refactor (icon-xref :text-uppercase-refactor))
|
||||
(def tick-refactor (icon-xref :tick-refactor))
|
||||
(def unlock-refactor (icon-xref :unlock-refactor))
|
||||
(def vertical-align-items-center-refactor (icon-xref :vertical-align-items-center-refactor))
|
||||
|
@ -375,6 +390,7 @@
|
|||
(def vertical-align-items-start-refactor (icon-xref :vertical-align-items-start-refactor))
|
||||
(def view-as-icons-refactor (icon-xref :view-as-icons-refactor))
|
||||
(def wrap-refactor (icon-xref :wrap-refactor))
|
||||
(def view-as-list-refactor (icon-xref :view-as-list-refactor))
|
||||
(def loader-pencil
|
||||
(mf/html
|
||||
[:svg
|
||||
|
|
|
@ -66,7 +66,7 @@
|
|||
(events/listen js/document EventType.KEYDOWN handle-keydown)
|
||||
|
||||
;; Changing to js/document breaks the color picker
|
||||
(events/listen (dom/get-root) EventType.POINTERDOWN handle-click-outside)
|
||||
(events/listen (dom/get-root) EventType.POINTERDOWN handle-click-outside)
|
||||
|
||||
(events/listen js/document EventType.CONTEXTMENU handle-click-outside)]]
|
||||
#(doseq [key keys]
|
||||
|
|
|
@ -169,7 +169,7 @@
|
|||
file-ready? (mf/deref file-ready*)
|
||||
|
||||
components-v2? (features/use-feature :components-v2)
|
||||
new-css? (features/use-feature :new-css-system)
|
||||
new-css-system (features/use-feature :new-css-system)
|
||||
|
||||
background-color (:background-color wglobal)]
|
||||
|
||||
|
@ -192,9 +192,9 @@
|
|||
[:& (mf/provider ctx/current-team-id) {:value team-id}
|
||||
[:& (mf/provider ctx/current-page-id) {:value page-id}
|
||||
[:& (mf/provider ctx/components-v2) {:value components-v2?}
|
||||
[:& (mf/provider ctx/new-css-system) {:value new-css?}
|
||||
[:& (mf/provider ctx/new-css-system) {:value new-css-system}
|
||||
[:& (mf/provider ctx/workspace-read-only?) {:value read-only?}
|
||||
[:section#workspace {:class (when new-css? (css :workspace))
|
||||
[:section#workspace {:class (when new-css-system (css :workspace))
|
||||
:style {:background-color background-color
|
||||
:touch-action "none"}}
|
||||
(when (not (:hide-ui layout))
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"button-primary":"ui_workspace_button-primary_FZJ-T","button-secondary":"ui_workspace_button-secondary_oDzCJ","button-icon":"ui_workspace_button-icon_L5y8h","button-icon-small":"ui_workspace_button-icon-small_Ppp3W","workspace":"ui_workspace_workspace_xutJr"}
|
||||
{"button-primary":"ui_workspace_button-primary_FZJ-T","button-secondary":"ui_workspace_button-secondary_oDzCJ","button-tertiary":"ui_workspace_button-tertiary_LVpr3","button-tag":"ui_workspace_button-tag_cU1Th","button-icon":"ui_workspace_button-icon_L5y8h","button-icon-small":"ui_workspace_button-icon-small_Ppp3W","asset-element":"ui_workspace_asset-element_LTbhl","workspace":"ui_workspace_workspace_xutJr"}
|
|
@ -1 +1 @@
|
|||
{"button-primary":"workspace_color_palette_button-primary_0d2e2","button-secondary":"workspace_color_palette_button-secondary_C8qJL","button-icon":"workspace_color_palette_button-icon_-tBR6","color-palette":"workspace_color_palette_color-palette_hfJPA","left-arrow":"workspace_color_palette_left-arrow_PK7sj","right-arrow":"workspace_color_palette_right-arrow_swpS9","button-icon-small":"workspace_color_palette_button-icon-small_RrGTg","disabled":"workspace_color_palette_disabled_bz-he","color-palette-content":"workspace_color_palette_color-palette-content_okg18","color-palette-inside":"workspace_color_palette_color-palette-inside_dCIeR","color-cell":"workspace_color_palette_color-cell_ITDgl","is-not-library-color":"workspace_color_palette_is-not-library-color_EqCM6","no-text":"workspace_color_palette_no-text_QMPK0"}
|
||||
{"button-primary":"workspace_color_palette_button-primary_0d2e2","button-secondary":"workspace_color_palette_button-secondary_C8qJL","button-tertiary":"workspace_color_palette_button-tertiary_X6-9C","button-tag":"workspace_color_palette_button-tag_GtZK2","button-icon":"workspace_color_palette_button-icon_-tBR6","color-palette":"workspace_color_palette_color-palette_hfJPA","left-arrow":"workspace_color_palette_left-arrow_PK7sj","right-arrow":"workspace_color_palette_right-arrow_swpS9","button-icon-small":"workspace_color_palette_button-icon-small_RrGTg","asset-element":"workspace_color_palette_asset-element_3Q2Mp","disabled":"workspace_color_palette_disabled_bz-he","color-palette-content":"workspace_color_palette_color-palette-content_okg18","color-palette-inside":"workspace_color_palette_color-palette-inside_dCIeR","color-cell":"workspace_color_palette_color-cell_ITDgl","is-not-library-color":"workspace_color_palette_is-not-library-color_EqCM6","no-text":"workspace_color_palette_no-text_QMPK0"}
|
|
@ -1 +1 @@
|
|||
{"button-primary":"workspace_color_palette_ctx_menu_button-primary_2ka4z","button-secondary":"workspace_color_palette_ctx_menu_button-secondary_jfajf","button-icon":"workspace_color_palette_ctx_menu_button-icon_cCaY2","button-icon-small":"workspace_color_palette_ctx_menu_button-icon-small_-knT4","palette-menu":"workspace_color_palette_ctx_menu_palette-menu_Vrjfy","palette-library":"workspace_color_palette_ctx_menu_palette-library_0LFV5","selected":"workspace_color_palette_ctx_menu_selected_lfchf","icon-wrapper":"workspace_color_palette_ctx_menu_icon-wrapper_v8-ys","recent-colors":"workspace_color_palette_ctx_menu_recent-colors_Q4fss","file-library":"workspace_color_palette_ctx_menu_file-library_8qsbr","option-wrapper":"workspace_color_palette_ctx_menu_option-wrapper_st9Cq","library-name":"workspace_color_palette_ctx_menu_library-name_BL8b8","color-sample":"workspace_color_palette_ctx_menu_color-sample_jQUGL"}
|
||||
{"button-primary":"workspace_color_palette_ctx_menu_button-primary_2ka4z","button-secondary":"workspace_color_palette_ctx_menu_button-secondary_jfajf","button-tertiary":"workspace_color_palette_ctx_menu_button-tertiary_NLctS","button-tag":"workspace_color_palette_ctx_menu_button-tag_GN3ad","button-icon":"workspace_color_palette_ctx_menu_button-icon_cCaY2","button-icon-small":"workspace_color_palette_ctx_menu_button-icon-small_-knT4","palette-menu":"workspace_color_palette_ctx_menu_palette-menu_Vrjfy","palette-library":"workspace_color_palette_ctx_menu_palette-library_0LFV5","selected":"workspace_color_palette_ctx_menu_selected_lfchf","icon-wrapper":"workspace_color_palette_ctx_menu_icon-wrapper_v8-ys","recent-colors":"workspace_color_palette_ctx_menu_recent-colors_Q4fss","file-library":"workspace_color_palette_ctx_menu_file-library_8qsbr","asset-element":"workspace_color_palette_ctx_menu_asset-element_pV16m","option-wrapper":"workspace_color_palette_ctx_menu_option-wrapper_st9Cq","library-name":"workspace_color_palette_ctx_menu_library-name_BL8b8","color-sample":"workspace_color_palette_ctx_menu_color-sample_jQUGL"}
|
|
@ -1 +1 @@
|
|||
{"button-primary":"workspace_context_menu_button-primary_d6q-P","button-secondary":"workspace_context_menu_button-secondary_bIdqe","button-icon":"workspace_context_menu_button-icon_tXvxe","button-icon-small":"workspace_context_menu_button-icon-small_c0rVU","workspace-context-menu":"workspace_context_menu_workspace-context-menu_2NyvR","icon-menu-item":"workspace_context_menu_icon-menu-item_P3-bA","shape-icon":"workspace_context_menu_shape-icon_xx1Ll","workspace-context-submenu":"workspace_context_menu_workspace-context-submenu_BUNLt","selected-icon":"workspace_context_menu_selected-icon_pZqBp","context-menu-item":"workspace_context_menu_context-menu-item_Tx-Ty","submenu-icon":"workspace_context_menu_submenu-icon_JwYm8","separator":"workspace_context_menu_separator_E9-aR","title":"workspace_context_menu_title_P8iFL","shortcut":"workspace_context_menu_shortcut_rypUe","shortcut-key":"workspace_context_menu_shortcut-key_3rF3t","icon-wrapper":"workspace_context_menu_icon-wrapper_n7VO2"}
|
||||
{"button-primary":"workspace_context_menu_button-primary_d6q-P","button-secondary":"workspace_context_menu_button-secondary_bIdqe","button-tertiary":"workspace_context_menu_button-tertiary_vGSns","button-tag":"workspace_context_menu_button-tag_rOUbd","button-icon":"workspace_context_menu_button-icon_tXvxe","button-icon-small":"workspace_context_menu_button-icon-small_c0rVU","workspace-context-menu":"workspace_context_menu_workspace-context-menu_2NyvR","icon-menu-item":"workspace_context_menu_icon-menu-item_P3-bA","shape-icon":"workspace_context_menu_shape-icon_xx1Ll","workspace-context-submenu":"workspace_context_menu_workspace-context-submenu_BUNLt","selected-icon":"workspace_context_menu_selected-icon_pZqBp","context-menu-item":"workspace_context_menu_context-menu-item_Tx-Ty","submenu-icon":"workspace_context_menu_submenu-icon_JwYm8","asset-element":"workspace_context_menu_asset-element_jkrbj","separator":"workspace_context_menu_separator_E9-aR","title":"workspace_context_menu_title_P8iFL","shortcut":"workspace_context_menu_shortcut_rypUe","shortcut-key":"workspace_context_menu_shortcut-key_3rF3t","icon-wrapper":"workspace_context_menu_icon-wrapper_n7VO2"}
|
|
@ -66,10 +66,10 @@
|
|||
(let [selected-drawtool (mf/deref refs/selected-drawing-tool)
|
||||
edition (mf/deref refs/selected-edition)
|
||||
|
||||
new-css? (mf/use-ctx ctx/new-css-system)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
|
||||
show-palette-btn? (and (not ^boolean read-only?) (not ^boolean new-css?))
|
||||
show-palette-btn? (and (not ^boolean read-only?) (not ^boolean new-css-system))
|
||||
|
||||
|
||||
interrupt
|
||||
|
|
|
@ -5,14 +5,20 @@
|
|||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.libraries
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.types.components-list :as ctkl]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.features :as features]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.search-bar :refer [search-bar]]
|
||||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
|
@ -56,6 +62,39 @@
|
|||
(conj (tr "workspace.libraries.typography" typography-count))))
|
||||
"\u00A0"))
|
||||
|
||||
(mf/defc describe-library-blocks
|
||||
[{:keys [components-count graphics-count colors-count typography-count] :as props}]
|
||||
|
||||
(let [last-one (cond
|
||||
(> colors-count 0) :color
|
||||
(> graphics-count 0) :graphics
|
||||
(> components-count 0) :components)]
|
||||
[:*
|
||||
(when (pos? components-count)
|
||||
[:*
|
||||
[:span {:class (css :element-count)}
|
||||
(tr "workspace.libraries.components" components-count)]
|
||||
(when (not= last-one :components)
|
||||
[:span " · "])])
|
||||
|
||||
(when (pos? graphics-count)
|
||||
[:*
|
||||
[:span {:class (css :element-count)}
|
||||
(tr "workspace.libraries.graphics" graphics-count)]
|
||||
(when (not= last-one :graphics)
|
||||
[:span " · "])])
|
||||
|
||||
(when (pos? colors-count)
|
||||
[:*
|
||||
[:span {:class (css :element-count)}
|
||||
(tr "workspace.libraries.colors" colors-count)]
|
||||
(when (not= last-one :colors)
|
||||
[:span " · "])])
|
||||
|
||||
(when (pos? typography-count)
|
||||
[:span {:class (css :element-count)}
|
||||
(tr "workspace.libraries.typography" typography-count)])]))
|
||||
|
||||
(defn- describe-linked-library
|
||||
[library]
|
||||
(let [components-count (count (or (ctkl/components-seq (:data library)) []))
|
||||
|
@ -75,16 +114,16 @@
|
|||
(mf/defc libraries-tab
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file-id shared? linked-libraries shared-libraries]}]
|
||||
(let [search-term* (mf/use-state "")
|
||||
search-term (deref search-term*)
|
||||
|
||||
library-ref (mf/with-memo [file-id]
|
||||
(create-file-library-ref file-id))
|
||||
library (deref library-ref)
|
||||
colors (:colors library)
|
||||
components (:components library)
|
||||
media (:media library)
|
||||
typographies (:typographies library)
|
||||
(let [search-term* (mf/use-state "")
|
||||
search-term (deref search-term*)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
library-ref (mf/with-memo [file-id]
|
||||
(create-file-library-ref file-id))
|
||||
library (deref library-ref)
|
||||
colors (:colors library)
|
||||
components (:components library)
|
||||
media (:media library)
|
||||
typographies (:typographies library)
|
||||
|
||||
shared-libraries
|
||||
(mf/with-memo [shared-libraries linked-libraries file-id search-term]
|
||||
|
@ -101,9 +140,12 @@
|
|||
|
||||
change-search-term
|
||||
(mf/use-fn
|
||||
(mf/deps new-css-system)
|
||||
(fn [event]
|
||||
(let [value (-> (dom/get-target event)
|
||||
(dom/get-value))]
|
||||
(let [value (if new-css-system
|
||||
event
|
||||
(-> (dom/get-target event)
|
||||
(dom/get-value)))]
|
||||
(reset! search-term* value))))
|
||||
|
||||
clear-search-term
|
||||
|
@ -111,20 +153,28 @@
|
|||
|
||||
link-library
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(mf/deps file-id new-css-system)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid))]
|
||||
(let [library-id (if new-css-system
|
||||
(some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid))
|
||||
(some-> (dom/get-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid)))]
|
||||
(st/emit! (dwl/link-file-to-library file-id library-id)))))
|
||||
|
||||
unlink-library
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid))]
|
||||
(let [library-id (if new-css-system
|
||||
(some-> (dom/get-current-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid))
|
||||
(some-> (dom/get-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid)))]
|
||||
(st/emit! (dwl/unlink-file-from-library file-id library-id)
|
||||
(dwl/sync-file file-id library-id)))))
|
||||
|
||||
|
@ -140,7 +190,10 @@
|
|||
publish
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
#(st/emit! (dwl/set-file-shared file-id true)))
|
||||
(fn [event]
|
||||
(let [input-node (dom/event->target event)]
|
||||
(st/emit! (dwl/set-file-shared file-id true))
|
||||
(dom/blur! input-node))))
|
||||
|
||||
unpublish
|
||||
(mf/use-fn
|
||||
|
@ -165,122 +218,230 @@
|
|||
(when ^boolean esc?
|
||||
(dom/blur! input-node)))))]
|
||||
|
||||
[:*
|
||||
[:div.section
|
||||
[:div.section-title (tr "workspace.libraries.in-this-file")]
|
||||
[:div.section-list
|
||||
(if new-css-system
|
||||
[:*
|
||||
[:div {:class (css :section)}
|
||||
[:& title-bar {:collapsable? false
|
||||
:title (tr "workspace.libraries.in-this-file")
|
||||
:klass :title-spacing-lib}]
|
||||
[:div {:class (css :section-list)}
|
||||
|
||||
[:div.section-list-item
|
||||
[:div
|
||||
[:div.item-name (tr "workspace.libraries.file-library")]
|
||||
[:div.item-contents (describe-library
|
||||
(count components)
|
||||
(count media)
|
||||
(count colors)
|
||||
(count typographies))]]
|
||||
[:div
|
||||
(if ^boolean shared?
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "common.unpublish")
|
||||
:on-click unpublish}]
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "common.publish")
|
||||
:on-click publish}])]]
|
||||
[:div {:class (css :section-list-item)}
|
||||
[:div
|
||||
[:div {:class (css :item-name)} (tr "workspace.libraries.file-library")]
|
||||
[:div {:class (css :item-contents)}
|
||||
[:& describe-library-blocks {:components-count (count components)
|
||||
:graphics-count (count media)
|
||||
:colors-count (count colors)
|
||||
:typography-count (count typographies)}]]]
|
||||
[:div
|
||||
(if ^boolean shared?
|
||||
[:input {:class (css :item-unpublish)
|
||||
:type "button"
|
||||
:value (tr "common.unpublish")
|
||||
:on-click unpublish}]
|
||||
[:input {:class (css :item-publish)
|
||||
:type "button"
|
||||
:value (tr "common.publish")
|
||||
:on-click publish}])]]
|
||||
|
||||
(for [{:keys [id name] :as library} linked-libraries]
|
||||
[:div.section-list-item {:key (dm/str id)}
|
||||
[:div.item-name name]
|
||||
[:div.item-contents (describe-linked-library library)]
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "labels.remove")
|
||||
:data-library-id (dm/str id)
|
||||
:on-click unlink-library}]])]]
|
||||
(for [{:keys [id name] :as library} linked-libraries]
|
||||
[:div {:class (css :section-list-item)
|
||||
:key (dm/str id)}
|
||||
[:div
|
||||
[:div {:class (css :item-name)} name]
|
||||
[:div {:class (css :item-contents)}
|
||||
(let [components-count (count (or (ctkl/components-seq (:data library)) []))
|
||||
graphics-count (count (dm/get-in library [:data :media] []))
|
||||
colors-count (count (dm/get-in library [:data :colors] []))
|
||||
typography-count (count (dm/get-in library [:data :typographies] []))]
|
||||
[:& describe-library-blocks {:components-count components-count
|
||||
:graphics-count graphics-count
|
||||
:colors-count colors-count
|
||||
:typography-count typography-count}])]]
|
||||
|
||||
[:div.section
|
||||
[:div.section-title (tr "workspace.libraries.shared-libraries")]
|
||||
[:div.libraries-search
|
||||
[:input.search-input
|
||||
{:placeholder (tr "workspace.libraries.search-shared-libraries")
|
||||
:type "text"
|
||||
:value search-term
|
||||
:on-change change-search-term
|
||||
:on-key-down handle-key-down}]
|
||||
(if (str/empty? search-term)
|
||||
[:div.search-icon
|
||||
i/search]
|
||||
[:div.search-icon.search-close
|
||||
{:on-click clear-search-term}
|
||||
i/close])]
|
||||
[:button {:class (css :item-button)
|
||||
:type "button"
|
||||
:data-library-id (dm/str id)
|
||||
:on-click unlink-library}
|
||||
i/delete-refactor]])]]
|
||||
|
||||
(if (seq shared-libraries)
|
||||
[:div {:class (css :section)}
|
||||
[:& title-bar {:collapsable? false
|
||||
:title (tr "workspace.libraries.shared-libraries")
|
||||
:klass :title-spacing-lib}]
|
||||
[:div {:class (css :libraries-search)}
|
||||
[:& search-bar {:on-change change-search-term
|
||||
:value search-term
|
||||
:placeholder (tr "workspace.libraries.search-shared-libraries")
|
||||
:icon (mf/html [:span {:class (css :search-icon)} i/search-refactor])}]]
|
||||
|
||||
(if (seq shared-libraries)
|
||||
[:div {:class (css :section-list)}
|
||||
(for [{:keys [id name] :as library} shared-libraries]
|
||||
[:div {:class (css :section-list-item)
|
||||
:key (dm/str id)}
|
||||
[:div
|
||||
[:div {:class (css :item-name)} name]
|
||||
[:div {:class (css :item-contents)}
|
||||
(let [components-count (dm/get-in library [:library-summary :components :count] 0)
|
||||
graphics-count (dm/get-in library [:library-summary :media :count] 0)
|
||||
colors-count (dm/get-in library [:library-summary :colors :count] 0)
|
||||
typography-count (dm/get-in library [:library-summary :typographies :count] 0)]
|
||||
[:& describe-library-blocks {:components-count components-count
|
||||
:graphics-count graphics-count
|
||||
:colors-count colors-count
|
||||
:typography-count typography-count}])]]
|
||||
[:button {:class (css :item-button)
|
||||
:data-library-id (dm/str id)
|
||||
:on-click link-library}
|
||||
i/add-refactor]])]
|
||||
|
||||
[:div {:class (css :section-list-empty)}
|
||||
(if (nil? shared-libraries)
|
||||
i/loader-pencil
|
||||
(if (str/empty? search-term)
|
||||
(tr "workspace.libraries.no-shared-libraries-available")
|
||||
(tr "workspace.libraries.no-matches-for" search-term)))])]]
|
||||
|
||||
[:*
|
||||
[:div.section
|
||||
[:div.section-title (tr "workspace.libraries.in-this-file")]
|
||||
[:div.section-list
|
||||
(for [{:keys [id name] :as library} shared-libraries]
|
||||
|
||||
[:div.section-list-item
|
||||
[:div
|
||||
[:div.item-name (tr "workspace.libraries.file-library")]
|
||||
[:div.item-contents (describe-library
|
||||
(count components)
|
||||
(count media)
|
||||
(count colors)
|
||||
(count typographies))]]
|
||||
[:div
|
||||
(if ^boolean shared?
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "common.unpublish")
|
||||
:on-click unpublish}]
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "common.publish")
|
||||
:on-click publish}])]]
|
||||
|
||||
(for [{:keys [id name] :as library} linked-libraries]
|
||||
[:div.section-list-item {:key (dm/str id)}
|
||||
[:div.item-name name]
|
||||
[:div.item-contents (describe-external-library library)]
|
||||
[:div.item-contents (describe-linked-library library)]
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "workspace.libraries.add")
|
||||
:value (tr "labels.remove")
|
||||
:data-library-id (dm/str id)
|
||||
:on-click link-library}]])]
|
||||
:on-click unlink-library}]])]]
|
||||
|
||||
[:div.section-list-empty
|
||||
(if (nil? shared-libraries)
|
||||
i/loader-pencil
|
||||
[:* i/library
|
||||
(if (str/empty? search-term)
|
||||
(tr "workspace.libraries.no-shared-libraries-available")
|
||||
(tr "workspace.libraries.no-matches-for" search-term))])])]]))
|
||||
[:div.section
|
||||
[:div.section-title (tr "workspace.libraries.shared-libraries")]
|
||||
[:div.libraries-search
|
||||
[:input.search-input
|
||||
{:placeholder (tr "workspace.libraries.search-shared-libraries")
|
||||
:type "text"
|
||||
:value search-term
|
||||
:on-change change-search-term
|
||||
:on-key-down handle-key-down}]
|
||||
(if (str/empty? search-term)
|
||||
[:div.search-icon
|
||||
i/search]
|
||||
[:div.search-icon.search-close
|
||||
{:on-click clear-search-term}
|
||||
i/close])]
|
||||
|
||||
(if (seq shared-libraries)
|
||||
[:div.section-list
|
||||
(for [{:keys [id name] :as library} shared-libraries]
|
||||
[:div.section-list-item {:key (dm/str id)}
|
||||
[:div.item-name name]
|
||||
[:div.item-contents (describe-external-library library)]
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "workspace.libraries.add")
|
||||
:data-library-id (dm/str id)
|
||||
:on-click link-library}]])]
|
||||
|
||||
[:div.section-list-empty
|
||||
(if (nil? shared-libraries)
|
||||
i/loader-pencil
|
||||
[:* i/library
|
||||
(if (str/empty? search-term)
|
||||
(tr "workspace.libraries.no-shared-libraries-available")
|
||||
(tr "workspace.libraries.no-matches-for" search-term))])])]])))
|
||||
|
||||
(mf/defc updates-tab
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file-id file-data libraries]}]
|
||||
(let [libraries (mf/with-memo [file-data libraries]
|
||||
(filter #(seq (dwl/assets-need-sync % file-data))
|
||||
(vals libraries)))
|
||||
(let [libraries (mf/with-memo [file-data libraries]
|
||||
(filter #(seq (dwl/assets-need-sync % file-data)) (vals libraries)))
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
update (mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid))]
|
||||
(st/emit! (dwl/sync-file file-id library-id)))))]
|
||||
[:div.section
|
||||
(if (empty? libraries)
|
||||
[:div.section-list-empty
|
||||
i/library
|
||||
(tr "workspace.libraries.no-libraries-need-sync")]
|
||||
[:*
|
||||
[:div.section-title (tr "workspace.libraries.library")]
|
||||
[:div.section-list
|
||||
(for [{:keys [id name] :as library} libraries]
|
||||
[:div.section-list-item {:key (dm/str id)}
|
||||
[:div.item-name name]
|
||||
[:div.item-contents (describe-external-library library)]
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "workspace.libraries.update")
|
||||
:data-library-id (dm/str id)
|
||||
:on-click update}]])]])]))
|
||||
update (mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(let [library-id (some-> (dom/get-target event)
|
||||
(dom/get-data "library-id")
|
||||
(parse-uuid))]
|
||||
(st/emit! (dwl/sync-file file-id library-id)))))]
|
||||
(if new-css-system
|
||||
[:div {:class (css :section)}
|
||||
(if (empty? libraries)
|
||||
[:div {:class (css :section-list-empty)}
|
||||
(tr "workspace.libraries.no-libraries-need-sync")]
|
||||
[:*
|
||||
[:div {:class (css :section-title)} (tr "workspace.libraries.library")]
|
||||
|
||||
[:div {:class (css :section-list)}
|
||||
(for [{:keys [id name] :as library} libraries]
|
||||
[:div {:class (css :section-list-item)
|
||||
:key (dm/str id)}
|
||||
[:div
|
||||
[:div {:class (css :item-name)} name]
|
||||
[:div {:class (css :item-contents)} (describe-external-library library)]]
|
||||
[:input {:class (css :item-update)
|
||||
:type "button"
|
||||
:value (tr "workspace.libraries.update")
|
||||
:data-library-id (dm/str id)
|
||||
:on-click update}]])]])]
|
||||
|
||||
[:div.section
|
||||
(if (empty? libraries)
|
||||
[:div.section-list-empty
|
||||
i/library
|
||||
(tr "workspace.libraries.no-libraries-need-sync")]
|
||||
[:*
|
||||
[:div.section-title (tr "workspace.libraries.library")]
|
||||
|
||||
[:div.section-list
|
||||
(for [{:keys [id name] :as library} libraries]
|
||||
[:div.section-list-item {:key (dm/str id)}
|
||||
[:div.item-name name]
|
||||
[:div.item-contents (describe-external-library library)]
|
||||
[:input.item-button {:type "button"
|
||||
:value (tr "workspace.libraries.update")
|
||||
:data-library-id (dm/str id)
|
||||
:on-click update}]])]])])))
|
||||
|
||||
(mf/defc libraries-dialog
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :libraries-dialog}
|
||||
[]
|
||||
(let [project (mf/deref refs/workspace-project)
|
||||
file-data (mf/deref refs/workspace-data)
|
||||
file (mf/deref ref:workspace-file)
|
||||
(let [new-css-system (features/use-feature :new-css-system)
|
||||
project (mf/deref refs/workspace-project)
|
||||
file-data (mf/deref refs/workspace-data)
|
||||
file (mf/deref ref:workspace-file)
|
||||
|
||||
team-id (:team-id project)
|
||||
file-id (:id file)
|
||||
shared? (:is-shared file)
|
||||
team-id (:team-id project)
|
||||
file-id (:id file)
|
||||
shared? (:is-shared file)
|
||||
|
||||
selected-tab* (mf/use-state :libraries)
|
||||
selected-tab (deref selected-tab*)
|
||||
selected-tab* (mf/use-state :libraries)
|
||||
selected-tab (deref selected-tab*)
|
||||
|
||||
libraries (mf/deref refs/workspace-libraries)
|
||||
libraries (mf/with-memo [libraries]
|
||||
(d/removem (fn [[_ val]] (:is-indirect val)) libraries))
|
||||
libraries (mf/deref refs/workspace-libraries)
|
||||
libraries (mf/with-memo [libraries]
|
||||
(d/removem (fn [[_ val]] (:is-indirect val)) libraries))
|
||||
|
||||
;; NOTE: we really don't need react on shared files
|
||||
shared-libraries
|
||||
|
@ -292,35 +453,61 @@
|
|||
select-updates-tab
|
||||
(mf/use-fn #(reset! selected-tab* :updates))
|
||||
|
||||
on-tab-change
|
||||
(mf/use-fn #(reset! selected-tab* %))
|
||||
|
||||
close-dialog
|
||||
(mf/use-fn #(modal/hide!))]
|
||||
(mf/use-fn (fn [_] (modal/hide!)
|
||||
(modal/disallow-click-outside!)))]
|
||||
|
||||
(mf/with-effect [team-id]
|
||||
(when team-id
|
||||
(st/emit! (dwl/fetch-shared-files {:team-id team-id}))))
|
||||
[:& (mf/provider ctx/new-css-system) {:value new-css-system}
|
||||
(if new-css-system
|
||||
[:div {:class (css :modal-overlay)}
|
||||
[:div {:class (css :modal-dialog)}
|
||||
[:div {:class (css :modal-content)}
|
||||
[:div {:class (css :libraries-header)}
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal.libraries-dialog
|
||||
[:a.close {:on-click close-dialog} i/close]
|
||||
[:div.modal-content
|
||||
[:div.libraries-header
|
||||
[:div.header-item
|
||||
{:class (dom/classnames :active (= selected-tab :libraries))
|
||||
:on-click select-libraries-tab}
|
||||
(tr "workspace.libraries.libraries")]
|
||||
[:div.header-item
|
||||
{:class (dom/classnames :active (= selected-tab :updates))
|
||||
:on-click select-updates-tab}
|
||||
(tr "workspace.libraries.updates")]]
|
||||
[:div.libraries-content
|
||||
(case selected-tab
|
||||
:libraries
|
||||
[:& libraries-tab {:file-id file-id
|
||||
:shared? shared?
|
||||
:linked-libraries libraries
|
||||
:shared-libraries shared-libraries}]
|
||||
:updates
|
||||
[:& updates-tab {:file-id file-id
|
||||
:file-data file-data
|
||||
:libraries libraries}])]]]]))
|
||||
[:& tab-container
|
||||
{:on-change-tab on-tab-change
|
||||
:selected selected-tab
|
||||
:collapsable? false}
|
||||
[:& tab-element {:id :libraries :title (tr "workspace.libraries.libraries")}
|
||||
[:div {:class (dom/classnames (css :libraries-content) true)}
|
||||
[:& libraries-tab {:file-id file-id
|
||||
:shared? shared?
|
||||
:linked-libraries libraries
|
||||
:shared-libraries shared-libraries}]]]
|
||||
[:& tab-element {:id :updates :title (tr "workspace.libraries.updates")}
|
||||
[:div {:class (dom/classnames (css :updates-content) true)}
|
||||
[:& updates-tab {:file-id file-id
|
||||
:file-data file-data
|
||||
:libraries libraries}]]]]]]]]
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal.libraries-dialog
|
||||
[:a.close {:on-click close-dialog} i/close]
|
||||
[:div.modal-content
|
||||
[:div.libraries-header
|
||||
[:div.header-item
|
||||
{:class (dom/classnames :active (= selected-tab :libraries))
|
||||
:on-click select-libraries-tab}
|
||||
(tr "workspace.libraries.libraries")]
|
||||
[:div.header-item
|
||||
{:class (dom/classnames :active (= selected-tab :updates))
|
||||
:on-click select-updates-tab}
|
||||
(tr "workspace.libraries.updates")]]
|
||||
[:div.libraries-content
|
||||
(case selected-tab
|
||||
:libraries
|
||||
[:& libraries-tab {:file-id file-id
|
||||
:shared? shared?
|
||||
:linked-libraries libraries
|
||||
:shared-libraries shared-libraries}]
|
||||
:updates
|
||||
[:& updates-tab {:file-id file-id
|
||||
:file-data file-data
|
||||
:libraries libraries}])]]]])]))
|
||||
|
||||
|
|
1
frontend/src/app/main/ui/workspace/libraries.css.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"button-primary":"workspace_libraries_button-primary_Hsioh","modal-overlay":"workspace_libraries_modal-overlay_qC-df","modal-dialog":"workspace_libraries_modal-dialog_Kj293","modal-content":"workspace_libraries_modal-content_4EVEQ","libraries-content":"workspace_libraries_libraries-content_ycQdm","section":"workspace_libraries_section_SUsgi","section-list":"workspace_libraries_section-list_lGSrM","section-list-item":"workspace_libraries_section-list-item_hwASN","item-publish":"workspace_libraries_item-publish_ZMopF","item-unpublish":"workspace_libraries_item-unpublish_1seca","item-update":"workspace_libraries_item-update_GklIE","updates-content":"workspace_libraries_updates-content_lqMoE","button-secondary":"workspace_libraries_button-secondary_l5M0x","button-tertiary":"workspace_libraries_button-tertiary_C54rH","item-button":"workspace_libraries_item-button_dKUeX","close":"workspace_libraries_close_bED7B","button-tag":"workspace_libraries_button-tag_wAh-s","button-icon":"workspace_libraries_button-icon_kxS7q","item-button-icon":"workspace_libraries_item-button-icon_CeJWg","button-icon-small":"workspace_libraries_button-icon-small_Q9eo3","section-list-empty":"workspace_libraries_section-list-empty_mOKkJ","libraries-search":"workspace_libraries_libraries-search_JS70w","search-icon":"workspace_libraries_search-icon_y7N9S","asset-element":"workspace_libraries_asset-element_-FuJl","libraries-header":"workspace_libraries_libraries-header_-W6bJ","item-name":"workspace_libraries_item-name_Zjbsw","item-contents":"workspace_libraries_item-contents_EPTF6","section-title":"workspace_libraries_section-title_7rsm7","element-count":"workspace_libraries_element-count_07SV2"}
|
139
frontend/src/app/main/ui/workspace/libraries.scss
Normal file
|
@ -0,0 +1,139 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
.modal-overlay {
|
||||
@include flexCenter;
|
||||
position: fixed;
|
||||
left: 0;
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
z-index: $z-index-modal;
|
||||
background-color: var(--overlay-color);
|
||||
pointer-events: none; // This is to allow outside click that closes modal.
|
||||
.modal-dialog {
|
||||
height: $s-400;
|
||||
max-height: 100%;
|
||||
width: $s-664;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--modal-background-color);
|
||||
pointer-events: all;
|
||||
.close {
|
||||
@extend .button-tertiary;
|
||||
width: $s-32;
|
||||
height: $s-32;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
.modal-content {
|
||||
.libraries-header {
|
||||
padding: $s-12;
|
||||
}
|
||||
|
||||
.libraries-content,
|
||||
.updates-content {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: $s-24;
|
||||
padding-top: $s-16;
|
||||
height: 100%;
|
||||
|
||||
.section {
|
||||
height: 100%;
|
||||
:global(.title-spacing-lib) {
|
||||
margin: 0 0 $s-8 calc(-1 * $s-8);
|
||||
}
|
||||
.section-list {
|
||||
height: 100%;
|
||||
max-height: 250px;
|
||||
overflow: auto;
|
||||
.section-list-item {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
margin-bottom: $s-12;
|
||||
|
||||
.item-name {
|
||||
@include titleTipography;
|
||||
color: var(--library-name-foreground-color);
|
||||
}
|
||||
.item-contents {
|
||||
@include titleTipography;
|
||||
color: var(--library-content-foreground-color);
|
||||
}
|
||||
|
||||
.item-publish,
|
||||
.item-unpublish,
|
||||
.item-update {
|
||||
@extend .button-primary;
|
||||
@include tabTitleTipography;
|
||||
height: $s-32;
|
||||
min-width: $s-92;
|
||||
padding: $s-8 $s-12;
|
||||
border-radius: $br-8;
|
||||
}
|
||||
.item-unpublish {
|
||||
@extend .button-secondary;
|
||||
}
|
||||
.item-button {
|
||||
@extend .button-tertiary;
|
||||
width: $s-32;
|
||||
height: $s-32;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
.item-button-icon {
|
||||
width: $s-28;
|
||||
height: $s-28;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.section-title {
|
||||
@include titleTipography;
|
||||
margin-bottom: $s-12;
|
||||
}
|
||||
.libraries-search {
|
||||
margin-bottom: $s-12;
|
||||
.search-icon {
|
||||
@include flexCenter;
|
||||
padding: 0 0 0 $s-8;
|
||||
width: $s-20;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
}
|
||||
}
|
||||
}
|
||||
.section-list-empty {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
width: $s-16;
|
||||
height: $s-16;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
.updates-content {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.element-count {
|
||||
white-space: nowrap;
|
||||
}
|
|
@ -1 +1 @@
|
|||
{"button-primary":"workspace_palette_button-primary_zEUyD","palettes":"workspace_palette_palettes_JHGUw","palette-actions":"workspace_palette_palette-actions_2GwR6","palette-btn-list":"workspace_palette_palette-btn-list_x7gPS","palette-item":"workspace_palette_palette-item_50uj6","palette-btn":"workspace_palette_palette-btn_kP66y","button-secondary":"workspace_palette_button-secondary_ksr24","button-icon":"workspace_palette_button-icon_pmEDv","button-icon-small":"workspace_palette_button-icon-small_vbLDq","wide":"workspace_palette_wide_3G4e1","mid-palette":"workspace_palette_mid-palette_rGR5I","small-palette":"workspace_palette_small-palette_18Otk","resize-area":"workspace_palette_resize-area_0LwVu","selected":"workspace_palette_selected_Z6BFo","palette":"workspace_palette_palette_eqp3q","handler":"workspace_palette_handler_4JV0J","handler-btn":"workspace_palette_handler-btn_7lnlF","hidden-bts":"workspace_palette_hidden-bts_mhbc0"}
|
||||
{"button-primary":"workspace_palette_button-primary_zEUyD","button-secondary":"workspace_palette_button-secondary_ksr24","button-tertiary":"workspace_palette_button-tertiary_91YQK","palettes":"workspace_palette_palettes_JHGUw","palette-actions":"workspace_palette_palette-actions_2GwR6","palette-btn-list":"workspace_palette_palette-btn-list_x7gPS","palette-item":"workspace_palette_palette-item_50uj6","palette-btn":"workspace_palette_palette-btn_kP66y","button-tag":"workspace_palette_button-tag_S9v-Z","button-icon":"workspace_palette_button-icon_pmEDv","button-icon-small":"workspace_palette_button-icon-small_vbLDq","asset-element":"workspace_palette_asset-element_4bXi3","wide":"workspace_palette_wide_3G4e1","mid-palette":"workspace_palette_mid-palette_rGR5I","small-palette":"workspace_palette_small-palette_18Otk","resize-area":"workspace_palette_resize-area_0LwVu","selected":"workspace_palette_selected_Z6BFo","palette":"workspace_palette_palette_eqp3q","handler":"workspace_palette_handler_4JV0J","handler-btn":"workspace_palette_handler-btn_7lnlF","hidden-bts":"workspace_palette_hidden-bts_mhbc0"}
|
|
@ -57,7 +57,7 @@
|
|||
opacity: $op-10;
|
||||
transition: opacity 1s ease;
|
||||
.palette-btn {
|
||||
@extend .button-primary;
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-32;
|
||||
border-radius: $br-8;
|
||||
|
@ -82,7 +82,7 @@
|
|||
}
|
||||
}
|
||||
.palette-actions {
|
||||
@extend .button-primary;
|
||||
@extend .button-tertiary;
|
||||
grid-area: actions;
|
||||
height: calc(var(--height) - $s-16);
|
||||
width: $s-32;
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.tab-container :refer [tab-container tab-element]]
|
||||
[app.main.ui.components.tabs-container :refer [tabs-container tabs-element]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks.resize :refer [use-resize-hook]]
|
||||
[app.main.ui.icons :as i]
|
||||
|
@ -40,7 +41,7 @@
|
|||
(contains? layout :assets) :assets)
|
||||
shortcuts? (contains? layout :shortcuts)
|
||||
show-debug? (contains? layout :debug-panel)
|
||||
new-css? (mf/use-ctx ctx/new-css-system)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
{:keys [on-pointer-down on-lost-pointer-capture on-pointer-move parent-ref size]}
|
||||
(use-resize-hook :left-sidebar 255 255 500 :x false :left)
|
||||
|
@ -49,12 +50,14 @@
|
|||
(mf/use-fn #(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar)))
|
||||
|
||||
on-tab-change
|
||||
(mf/use-fn #(st/emit! (dw/go-to-layout %)))
|
||||
]
|
||||
(mf/use-fn #(st/emit! (dw/go-to-layout %)))]
|
||||
|
||||
[:aside {:ref parent-ref
|
||||
:class (if ^boolean new-css?
|
||||
(dom/classnames (css :left-settings-bar) true)
|
||||
:class (if ^boolean new-css-system
|
||||
(dom/classnames (css :left-settings-bar) true
|
||||
:two-row (<= size 300)
|
||||
:three-row (and (> size 300) (<= size 400))
|
||||
:four-row (> size 400))
|
||||
(dom/classnames :settings-bar true
|
||||
:settings-bar-left true
|
||||
:two-row (<= size 300)
|
||||
|
@ -65,10 +68,10 @@
|
|||
[:div {:on-pointer-down on-pointer-down
|
||||
:on-lost-pointer-capture on-lost-pointer-capture
|
||||
:on-pointer-move on-pointer-move
|
||||
:class (if ^boolean new-css?
|
||||
:class (if ^boolean new-css-system
|
||||
(dom/classnames (css :resize-area) true)
|
||||
(dom/classnames :resize-area true))}]
|
||||
[:div {:class (if ^boolean new-css?
|
||||
[:div {:class (if ^boolean new-css-system
|
||||
(dom/classnames (css :settings-bar-inside) true)
|
||||
(dom/classnames :settings-bar-inside true))}
|
||||
(cond
|
||||
|
@ -79,22 +82,23 @@
|
|||
[:& debug-panel]
|
||||
|
||||
:else
|
||||
(if ^boolean new-css?
|
||||
[:& tab-container
|
||||
{:on-change-tab on-tab-change
|
||||
:selected section
|
||||
:shortcuts? shortcuts?
|
||||
:collapsable? true
|
||||
:handle-collapse handle-collapse}
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :tabs-wrapper) true)}
|
||||
[:& tab-container
|
||||
{:on-change-tab on-tab-change
|
||||
:selected section
|
||||
:shortcuts? shortcuts?
|
||||
:collapsable? true
|
||||
:handle-collapse handle-collapse
|
||||
:klass :tab-spacing}
|
||||
[:& tab-element {:id :layers :title (tr "workspace.sidebar.layers")}
|
||||
[:div {:class (dom/classnames (css :layers-tab) true)}
|
||||
[:& sitemap {:layout layout}]
|
||||
[:& layers-toolbox {:size-parent size}]]]
|
||||
|
||||
[:& tab-element {:id :layers :title (tr "workspace.sidebar.layers")}
|
||||
[:div {:class (dom/classnames (css :layers-tab) true)}
|
||||
[:& sitemap {:layout layout}]
|
||||
[:& layers-toolbox {:size-parent size}]]]
|
||||
|
||||
(when-not ^boolean mode-inspect?
|
||||
[:& tab-element {:id :assets :title (tr "workspace.toolbar.assets")}
|
||||
[:& assets-toolbox]])]
|
||||
(when-not ^boolean mode-inspect?
|
||||
[:& tab-element {:id :assets :title (tr "workspace.toolbar.assets")}
|
||||
[:& assets-toolbox]])]]
|
||||
|
||||
[:*
|
||||
[:button.collapse-sidebar
|
||||
|
@ -102,20 +106,20 @@
|
|||
:aria-label (tr "workspace.sidebar.collapse")}
|
||||
i/arrow-slide]
|
||||
|
||||
[:& tab-container
|
||||
[:& tabs-container
|
||||
{:on-change-tab on-tab-change
|
||||
:selected section
|
||||
:shortcuts? shortcuts?
|
||||
:collapsable? true
|
||||
:handle-collapse handle-collapse}
|
||||
|
||||
[:& tab-element {:id :layers :title (tr "workspace.sidebar.layers")}
|
||||
[:& tabs-element {:id :layers :title (tr "workspace.sidebar.layers")}
|
||||
[:div {:class (dom/classnames :layers-tab true)}
|
||||
[:& sitemap {:layout layout}]
|
||||
[:& layers-toolbox {:size-parent size}]]]
|
||||
|
||||
(when-not ^boolean mode-inspect?
|
||||
[:& tab-element {:id :assets :title (tr "workspace.toolbar.assets")}
|
||||
[:& tabs-element {:id :assets :title (tr "workspace.toolbar.assets")}
|
||||
[:& assets-toolbox]])]]))]]))
|
||||
|
||||
;; --- Right Sidebar (Component)
|
||||
|
@ -150,4 +154,3 @@
|
|||
|
||||
:else
|
||||
[:> options-toolbox props])]]))
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"button-primary":"workspace_sidebar_button-primary_K7xW6","button-secondary":"workspace_sidebar_button-secondary_e2eQE","button-icon":"workspace_sidebar_button-icon_OXdmL","button-icon-small":"workspace_sidebar_button-icon-small_EYb9x","left-settings-bar":"workspace_sidebar_left-settings-bar_7co5t","resize-area":"workspace_sidebar_resize-area_ny1v0","settings-bar-inside":"workspace_sidebar_settings-bar-inside_YnFv8","layers-tab":"workspace_sidebar_layers-tab_soxRL"}
|
||||
{"button-primary":"workspace_sidebar_button-primary_K7xW6","button-secondary":"workspace_sidebar_button-secondary_e2eQE","button-tertiary":"workspace_sidebar_button-tertiary_QKqHT","button-tag":"workspace_sidebar_button-tag_Xc0Sm","button-icon":"workspace_sidebar_button-icon_OXdmL","button-icon-small":"workspace_sidebar_button-icon-small_EYb9x","asset-element":"workspace_sidebar_asset-element_vzrfV","left-settings-bar":"workspace_sidebar_left-settings-bar_7co5t","resize-area":"workspace_sidebar_resize-area_ny1v0","settings-bar-inside":"workspace_sidebar_settings-bar-inside_YnFv8","tabs-wrapper":"workspace_sidebar_tabs-wrapper_YDo4o","layers-tab":"workspace_sidebar_layers-tab_soxRL"}
|
|
@ -33,12 +33,17 @@ $width-settings-bar-max: 500px;
|
|||
grid-template-columns: 100%;
|
||||
grid-template-rows: 100%;
|
||||
height: calc(100% - 2px);
|
||||
.layers-tab {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-columns: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
.tabs-wrapper {
|
||||
.layers-tab {
|
||||
display: grid;
|
||||
grid-template-rows: auto 1fr;
|
||||
grid-template-columns: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
:global(.tab-spacing) {
|
||||
margin: $s-4 $s-4 0 $s-4;
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"sidebar_assets_button-primary_a9p4J","button-secondary":"sidebar_assets_button-secondary_hbgBA","assets-bar":"sidebar_assets_assets-bar_gzAPj","libraries-button":"sidebar_assets_libraries-button_cKUY7","button-tertiary":"sidebar_assets_button-tertiary_KoPen","button-tag":"sidebar_assets_button-tag_yzpPm","button-icon":"sidebar_assets_button-icon_M5Yy6","libraries-icon":"sidebar_assets_libraries-icon_ikusB","button-icon-small":"sidebar_assets_button-icon-small_xZWe1","asset-element":"sidebar_assets_asset-element_xHJzG","section-button":"sidebar_assets_section-button_RSjn8","sections-container":"sidebar_assets_sections-container_r2YTM","section-item":"sidebar_assets_section-item_u6EYM","section-btn":"sidebar_assets_section-btn_s4h2P","libraries-wrapper":"sidebar_assets_libraries-wrapper_agaHg","assets-header":"sidebar_assets_assets-header_aFHCj"}
|
119
frontend/src/app/main/ui/workspace/sidebar/assets.scss
Normal file
|
@ -0,0 +1,119 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.assets-bar {
|
||||
position: relative;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
.libraries-button {
|
||||
@include tabTitleTipography;
|
||||
@extend .button-secondary;
|
||||
gap: $s-2;
|
||||
height: $s-32;
|
||||
width: 100%;
|
||||
border-radius: $s-8;
|
||||
margin-bottom: $s-4;
|
||||
.libraries-icon {
|
||||
@include flexCenter;
|
||||
width: $s-24;
|
||||
height: 100%;
|
||||
svg {
|
||||
@include flexCenter;
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--button-secondary-background-color-hover);
|
||||
color: var(--button-secondary-foreground-color-hover);
|
||||
border: $s-1 solid var(--button-secondary-border-color-hover);
|
||||
svg {
|
||||
stroke: var(--button-secondary-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
&:focus {
|
||||
background-color: var(--button-secondary-background-color-focus);
|
||||
color: var(--button-secondary-foreground-color-focus);
|
||||
border: $s-1 solid var(--button-secondary-border-color-focus);
|
||||
svg {
|
||||
stroke: var(--button-secondary-foreground-color-focus);
|
||||
}
|
||||
}
|
||||
}
|
||||
.section-button {
|
||||
@include flexCenter;
|
||||
@include buttonStyle;
|
||||
height: $s-32;
|
||||
width: $s-32;
|
||||
margin: 0;
|
||||
border: 1px solid var(--color-background-tertiary);
|
||||
border-radius: $br-8 $br-2 $br-2 $br-8;
|
||||
background-color: var(--color-background-tertiary);
|
||||
svg {
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
stroke: var(--icon-foreground);
|
||||
}
|
||||
&:focus {
|
||||
border: 1px solid var(--input-border-color-focus);
|
||||
outline: 0;
|
||||
background-color: var(--input-background-color-active);
|
||||
color: var(--input-foreground-color-active);
|
||||
svg {
|
||||
background-color: var(--input-background-color-active);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
border: 1px solid var(--input-background-color-hover);
|
||||
background-color: var(--input-background-color-hover);
|
||||
svg {
|
||||
background-color: var(--input-background-color-hover);
|
||||
stroke: var(--button-foreground-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
.sections-container {
|
||||
position: absolute;
|
||||
top: $s-84;
|
||||
left: $s-12;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: $s-4;
|
||||
width: $s-192;
|
||||
padding: $s-4;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--menu-background-color);
|
||||
z-index: $z-index-4;
|
||||
box-shadow: 0px 0px 10px 0px var(--menu-shadow-color);
|
||||
.section-item {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
width: 100%;
|
||||
padding: $s-6;
|
||||
border-radius: $br-8;
|
||||
.section-btn {
|
||||
@include buttonStyle;
|
||||
}
|
||||
}
|
||||
}
|
||||
.libraries-wrapper {
|
||||
overflow: auto;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: calc(100% - $s-72);
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
scrollbar-gutter: stable;
|
||||
overflow-y: overlay;
|
||||
}
|
||||
.assets-header {
|
||||
padding: $s-8 $s-12 $s-4 $s-12;
|
||||
}
|
||||
}
|
621
frontend/src/app/main/ui/workspace/sidebar/assets/colors.cljs
Normal file
|
@ -0,0 +1,621 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.assets.colors
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.colors :as dc]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.color-bullet :as bc]
|
||||
[app.main.ui.components.color-bullet-new :as cb]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||
[app.util.color :as uc]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[potok.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc color-item
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [color local? file-id selected multi-colors? multi-assets?
|
||||
on-asset-click on-assets-delete on-clear-selection on-group
|
||||
selected-full selected-paths move-color]}]
|
||||
|
||||
(let [color (mf/with-memo [color file-id]
|
||||
(cond-> color
|
||||
(:value color) (assoc :color (:value color) :opacity 1)
|
||||
(:value color) (dissoc :value)
|
||||
true (assoc :file-id file-id)))
|
||||
|
||||
|
||||
color-id (:id color)
|
||||
|
||||
item-ref (mf/use-ref)
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
rename? (= (:color-for-rename @refs/workspace-local) color-id)
|
||||
input-ref (mf/use-ref)
|
||||
|
||||
editing* (mf/use-state rename?)
|
||||
editing? (deref editing*)
|
||||
|
||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
default-name (cond
|
||||
(:gradient color) (uc/gradient-type->string (dm/get-in color [:gradient :type]))
|
||||
(:color color) (:color color)
|
||||
:else (:value color))
|
||||
|
||||
apply-color
|
||||
(mf/use-fn
|
||||
(mf/deps color)
|
||||
(fn [event]
|
||||
(st/emit! (dc/apply-color-from-palette (merge uc/empty-color color) (kbd/alt? event)))))
|
||||
|
||||
rename-color
|
||||
(mf/use-fn
|
||||
(mf/deps file-id color-id)
|
||||
(fn [name]
|
||||
(st/emit! (dwl/rename-color file-id color-id name))))
|
||||
|
||||
edit-color
|
||||
(mf/use-fn
|
||||
(mf/deps color file-id)
|
||||
(fn [attrs]
|
||||
(let [name (cph/merge-path-item (:path color) (:name color))
|
||||
color (-> attrs
|
||||
(assoc :id (:id color))
|
||||
(assoc :file-id file-id)
|
||||
(assoc :name name))]
|
||||
(st/emit! (dwl/update-color color file-id)))))
|
||||
|
||||
delete-color
|
||||
(mf/use-fn
|
||||
(mf/deps multi-colors? multi-assets? file-id color-id)
|
||||
(fn []
|
||||
(if (or multi-colors? multi-assets?)
|
||||
(on-assets-delete)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id)
|
||||
(dwl/delete-color color)
|
||||
(dwl/sync-file file-id file-id :colors color-id)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
rename-color-clicked
|
||||
(mf/use-fn
|
||||
(mf/deps read-only? local?)
|
||||
(fn [event]
|
||||
(when (and local? (not read-only?))
|
||||
(dom/prevent-default event)
|
||||
(reset! editing* true))))
|
||||
|
||||
input-blur
|
||||
(mf/use-fn
|
||||
(mf/deps rename-color)
|
||||
(fn [event]
|
||||
(let [target (dom/event->target event)
|
||||
name (dom/get-value target)]
|
||||
(rename-color name)
|
||||
(st/emit! dwl/clear-color-for-rename)
|
||||
(reset! editing* false))))
|
||||
|
||||
input-key-down
|
||||
(mf/use-fn
|
||||
(mf/deps input-blur)
|
||||
(fn [event]
|
||||
(when (kbd/esc? event)
|
||||
(st/emit! dwl/clear-color-for-rename)
|
||||
(reset! editing* false))
|
||||
(when (kbd/enter? event)
|
||||
(input-blur event))))
|
||||
|
||||
edit-color-clicked
|
||||
(mf/use-fn
|
||||
(mf/deps edit-color color)
|
||||
(fn [event]
|
||||
(modal/show! :colorpicker
|
||||
{:x (.-clientX ^js event)
|
||||
:y (.-clientY ^js event)
|
||||
:on-accept edit-color
|
||||
:data color
|
||||
:position :right})))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps color-id selected on-clear-selection read-only?)
|
||||
(fn [event]
|
||||
(dom/prevent-default event)
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(when (and local? (not read-only?))
|
||||
(when-not (contains? selected color-id)
|
||||
(on-clear-selection))
|
||||
(swap! menu-state cmm/open-context-menu pos)))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state cmm/close-context-menu)))
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps color dragging* selected selected-full selected-paths move-color)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset event color dragging* selected selected-full
|
||||
selected-paths move-color)))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps color dragging* selected selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset event color dragging* selected selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-color-drag-start
|
||||
(mf/use-fn
|
||||
(mf/deps color file-id selected item-ref read-only?)
|
||||
(fn [event]
|
||||
(if read-only?
|
||||
(dom/prevent-default event)
|
||||
(cmm/on-asset-drag-start event file-id color selected item-ref :colors identity))))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps color-id apply-color on-asset-click)
|
||||
(partial on-asset-click color-id apply-color))]
|
||||
|
||||
(mf/with-effect [editing?]
|
||||
(when editing?
|
||||
(let [input (mf/ref-val input-ref)]
|
||||
(dom/select-text! input)
|
||||
nil)))
|
||||
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :asset-list-item) true
|
||||
(css :selected) (contains? selected (:id color))
|
||||
(css :editing) editing?)
|
||||
:style #js {"--bullet-size" "16px"}
|
||||
:on-context-menu on-context-menu
|
||||
:on-click (when-not editing? on-click)
|
||||
:ref item-ref
|
||||
:draggable (and (not read-only?) (not editing?))
|
||||
:on-drag-start on-color-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
[:div {:class (dom/classnames (css :bullet-block) true)}
|
||||
[:& cb/color-bullet {:color color
|
||||
:mini? true}]]
|
||||
|
||||
(if ^boolean editing?
|
||||
[:input
|
||||
{:type "text"
|
||||
:class (dom/classnames (css :element-name) true)
|
||||
:ref input-ref
|
||||
:on-blur input-blur
|
||||
:on-key-down input-key-down
|
||||
:auto-focus true
|
||||
:default-value (cph/merge-path-item (:path color) (:name color))}]
|
||||
|
||||
[:div {:title (:name color)
|
||||
:class (dom/classnames (css :name-block) true)
|
||||
:on-double-click rename-color-clicked}
|
||||
|
||||
(if (= (:name color) default-name)
|
||||
[:span {:class (dom/classnames (css :default-name-only) true)} default-name]
|
||||
[:*
|
||||
[:span {:class (dom/classnames (css :name) true)} (:name color)]
|
||||
[:span {:class (dom/classnames (css :default-name) true)} default-name]])])
|
||||
|
||||
(when local?
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options [(when-not (or multi-colors? multi-assets?)
|
||||
{:option-name (tr "workspace.assets.rename")
|
||||
:id "assets-rename-color"
|
||||
:option-handler rename-color-clicked})
|
||||
(when-not (or multi-colors? multi-assets?)
|
||||
{:option-name (tr "workspace.assets.edit")
|
||||
:id "assets-edit-color"
|
||||
:option-handler edit-color-clicked})
|
||||
|
||||
{:option-name (tr "workspace.assets.delete")
|
||||
:id "assets-delete-color"
|
||||
:option-handler delete-color}
|
||||
(when-not multi-assets?
|
||||
{:option-name (tr "workspace.assets.group")
|
||||
:id "assets-group-color"
|
||||
:option-handler (on-group (:id color))})]}])
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (dom/classnames (css :dragging) true)}])]
|
||||
|
||||
[:div.asset-list-item
|
||||
{:class-name (dom/classnames
|
||||
:selected (contains? selected (:id color)))
|
||||
:on-context-menu on-context-menu
|
||||
:on-click (when-not editing? on-click)
|
||||
:ref item-ref
|
||||
:draggable (and (not read-only?) (not editing?))
|
||||
:on-drag-start on-color-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
[:& bc/color-bullet {:color color}]
|
||||
|
||||
(if ^boolean editing?
|
||||
[:input.element-name
|
||||
{:type "text"
|
||||
:ref input-ref
|
||||
:on-blur input-blur
|
||||
:on-key-down input-key-down
|
||||
:auto-focus true
|
||||
:default-value (cph/merge-path-item (:path color) (:name color))}]
|
||||
|
||||
[:div.name-block {:title (:name color)
|
||||
:on-double-click rename-color-clicked}
|
||||
(:name color)
|
||||
(when-not (= (:name color) default-name)
|
||||
[:span default-name])])
|
||||
|
||||
(when local?
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options [(when-not (or multi-colors? multi-assets?)
|
||||
[(tr "workspace.assets.rename") rename-color-clicked])
|
||||
(when-not (or multi-colors? multi-assets?)
|
||||
[(tr "workspace.assets.edit") edit-color-clicked])
|
||||
[(tr "workspace.assets.delete") delete-color]
|
||||
(when-not multi-assets?
|
||||
[(tr "workspace.assets.group") (on-group (:id color))])]}])
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.dragging])])))
|
||||
|
||||
(mf/defc colors-group
|
||||
[{:keys [file-id prefix groups open-groups local? selected
|
||||
multi-colors? multi-assets? on-asset-click on-assets-delete
|
||||
on-clear-selection on-group on-rename-group on-ungroup colors
|
||||
selected-full]}]
|
||||
(let [group-open? (get open-groups prefix true)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
selected-paths (mf/with-memo [selected-full]
|
||||
(into #{}
|
||||
(comp (map :path) (d/nilv ""))
|
||||
selected-full))
|
||||
|
||||
move-color
|
||||
(mf/use-fn (mf/deps file-id) (partial dwl/rename-color file-id))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset-group event dragging* prefix selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths selected-full move-color)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full move-color)))]
|
||||
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :colors-group) true)
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title {:file-id file-id
|
||||
:section :colors
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [colors (get groups "" [])]
|
||||
[:div {:class (dom/classnames (css :asset-list) true)
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (dom/classnames (css :grid-placeholder) true)}
|
||||
"\u00A0"])
|
||||
|
||||
(when (and (empty? colors)
|
||||
(some? groups))
|
||||
[:div {:class (dom/classnames (css :drop-space) true)}])
|
||||
|
||||
(for [color colors]
|
||||
[:& color-item {:key (dm/str (:id color))
|
||||
:color color
|
||||
:file-id file-id
|
||||
:local? local?
|
||||
:selected selected
|
||||
:multi-colors? multi-colors?
|
||||
:multi-assets? multi-assets?
|
||||
:on-asset-click on-asset-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection
|
||||
:on-group on-group
|
||||
:colors colors
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths
|
||||
:move-color move-color}])])
|
||||
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& colors-group {:file-id file-id
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:key (dm/str "group-" path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:local? local?
|
||||
:selected selected
|
||||
:multi-colors? multi-colors?
|
||||
:multi-assets? multi-assets?
|
||||
:on-asset-click on-asset-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection
|
||||
:on-group on-group
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:colors colors
|
||||
:selected-full selected-full}]))])]
|
||||
|
||||
|
||||
[:div {:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title {:file-id file-id
|
||||
:section :colors
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [colors (get groups "" [])]
|
||||
[:div.asset-list {:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.grid-placeholder "\u00A0"])
|
||||
|
||||
(when (and (empty? colors)
|
||||
(some? groups))
|
||||
[:div.drop-space])
|
||||
|
||||
(for [color colors]
|
||||
[:& color-item {:key (dm/str (:id color))
|
||||
:color color
|
||||
:file-id file-id
|
||||
:local? local?
|
||||
:selected selected
|
||||
:multi-colors? multi-colors?
|
||||
:multi-assets? multi-assets?
|
||||
:on-asset-click on-asset-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection
|
||||
:on-group on-group
|
||||
:colors colors
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths
|
||||
:move-color move-color}])])
|
||||
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& colors-group {:file-id file-id
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:key (dm/str "group-" path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:local? local?
|
||||
:selected selected
|
||||
:multi-colors? multi-colors?
|
||||
:multi-assets? multi-assets?
|
||||
:on-asset-click on-asset-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection
|
||||
:on-group on-group
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:colors colors
|
||||
:selected-full selected-full}]))])])))
|
||||
|
||||
(mf/defc colors-section
|
||||
[{:keys [file-id local? colors open? open-status-ref selected reverse-sort?
|
||||
on-asset-click on-assets-delete on-clear-selection] :as props}]
|
||||
|
||||
(let [selected (:colors selected)
|
||||
selected-full (mf/with-memo [selected colors]
|
||||
(into #{} (filter #(contains? selected (:id %))) colors))
|
||||
|
||||
open-groups-ref (mf/with-memo [open-status-ref]
|
||||
(-> (l/in [:groups :colors])
|
||||
(l/derived open-status-ref)))
|
||||
open-groups (mf/deref open-groups-ref)
|
||||
|
||||
multi-colors? (> (count selected) 1)
|
||||
multi-assets? (or (seq (:components selected))
|
||||
(seq (:graphics selected))
|
||||
(seq (:typographies selected)))
|
||||
|
||||
groups (mf/with-memo [colors reverse-sort?]
|
||||
(grp/group-assets colors reverse-sort?))
|
||||
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
add-color
|
||||
(mf/use-fn
|
||||
(fn [value _]
|
||||
(st/emit! (dwl/add-color value))))
|
||||
|
||||
add-color-clicked
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [event]
|
||||
(st/emit! (dw/set-assets-section-open file-id :colors true)
|
||||
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
|
||||
:asset-type "color"}))
|
||||
(modal/show! :colorpicker
|
||||
{:x (.-clientX event)
|
||||
:y (.-clientY event)
|
||||
:on-accept add-color
|
||||
:data {:color "#406280"
|
||||
:opacity 1}
|
||||
:position :right})))
|
||||
|
||||
create-group
|
||||
(mf/use-fn
|
||||
(mf/deps colors selected on-clear-selection file-id)
|
||||
(fn [color-id]
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> colors
|
||||
(filter #(if multi-colors?
|
||||
(contains? selected (:id %))
|
||||
(= color-id (:id %))))
|
||||
(map #(dwl/update-color
|
||||
(assoc % :name
|
||||
(cmm/add-group % group-name))
|
||||
file-id))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps colors)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> colors
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/update-color
|
||||
(assoc % :name
|
||||
(cmm/rename-group % path last-path))
|
||||
file-id))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-group
|
||||
(mf/use-fn
|
||||
(mf/deps colors selected)
|
||||
(fn [color-id]
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept (create-group color-id)}))))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps colors)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:path path
|
||||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
on-ungroup
|
||||
(mf/use-fn
|
||||
(mf/deps colors)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(apply st/emit!
|
||||
(->> colors
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/update-color
|
||||
(assoc % :name
|
||||
(cmm/ungroup % path))
|
||||
file-id))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn (mf/deps groups on-asset-click) (partial on-asset-click groups))]
|
||||
|
||||
|
||||
[:& cmm/asset-section {:file-id file-id
|
||||
:title (tr "workspace.assets.colors")
|
||||
:section :colors
|
||||
:assets-count (count colors)
|
||||
:open? open?}
|
||||
(if ^boolean new-css-system
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when-not read-only?
|
||||
[:button {:class (dom/classnames (css :assets-btn) true)
|
||||
:on-click add-color-clicked}
|
||||
i/add-refactor])])
|
||||
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when-not read-only?
|
||||
[:div.assets-button {:on-click add-color-clicked}
|
||||
i/plus])]))
|
||||
|
||||
|
||||
[:& cmm/asset-section-block {:role :content}
|
||||
[:& colors-group {:file-id file-id
|
||||
:prefix ""
|
||||
:groups groups
|
||||
:open-groups open-groups
|
||||
:local? local?
|
||||
:selected selected
|
||||
:multi-colors? multi-colors?
|
||||
:multi-assets? multi-assets?
|
||||
:on-asset-click on-asset-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection
|
||||
:on-group on-group
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:colors colors
|
||||
:selected-full selected-full}]]]))
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"assets_colors_button-primary_6ZMmx","button-secondary":"assets_colors_button-secondary_dNSLH","button-tertiary":"assets_colors_button-tertiary_h20-o","assets-btn":"assets_colors_assets-btn_t8DHG","button-tag":"assets_colors_button-tag_ux-NH","button-icon":"assets_colors_button-icon_f-EVH","button-icon-small":"assets_colors_button-icon-small_zq8dv","asset-element":"assets_colors_asset-element_XSxD1","colors-group":"assets_colors_colors-group_fUsuo","asset-list":"assets_colors_asset-list_wMm1l","asset-list-item":"assets_colors_asset-list-item_ZFtXC","bullet-block":"assets_colors_bullet-block_ZRR2Y","name-block":"assets_colors_name-block_Zvmy3","default-name-only":"assets_colors_default-name-only_JFCGo","name":"assets_colors_name_AjZzr","default-name":"assets_colors_default-name_8gEAb","element-name":"assets_colors_element-name_ADGM8","selected":"assets_colors_selected_ElMu0","editing":"assets_colors_editing_FWnHU","grid-placeholder":"assets_colors_grid-placeholder_7wTFd","drop-space":"assets_colors_drop-space_lbzeC","dragging":"assets_colors_dragging_EmBOk"}
|
102
frontend/src/app/main/ui/workspace/sidebar/assets/colors.scss
Normal file
|
@ -0,0 +1,102 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.assets-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: calc($s-24 + $s-4);
|
||||
padding: 0;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
|
||||
.colors-group {
|
||||
margin-top: $s-4;
|
||||
.asset-list {
|
||||
padding: 0 0 0 $s-12;
|
||||
.asset-list-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-32;
|
||||
padding: $s-8 $s-12 $s-8 $s-8;
|
||||
margin-bottom: $s-4;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
cursor: pointer;
|
||||
.bullet-block {
|
||||
@include flexCenter;
|
||||
height: 100%;
|
||||
width: $s-32;
|
||||
}
|
||||
.name-block {
|
||||
@include titleTipography;
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
.default-name-only,
|
||||
.name {
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
margin-right: $s-6;
|
||||
@include textEllipsis;
|
||||
}
|
||||
.default-name {
|
||||
min-width: 0;
|
||||
color: var(--assets-item-name-foreground-color);
|
||||
}
|
||||
}
|
||||
.element-name {
|
||||
@include textEllipsis;
|
||||
color: var(--color-foreground-primary);
|
||||
}
|
||||
&.selected {
|
||||
border: $s-1 solid var(--assets-item-border-color);
|
||||
}
|
||||
|
||||
&.editing {
|
||||
border: $s-1 solid var(--input-border-color-focus);
|
||||
input.element-name {
|
||||
@include textEllipsis;
|
||||
@include titleTipography;
|
||||
@include removeInputStyle;
|
||||
flex-grow: 1;
|
||||
height: $s-28;
|
||||
max-width: calc(var(--parent-size) - (var(--depth) * var(--layer-indentation-size)));
|
||||
margin: 0;
|
||||
color: var(--layer-row-foreground-color);
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
.grid-placeholder {
|
||||
height: $s-2;
|
||||
margin-bottom: $s-2;
|
||||
background-color: var(--color-accent-primary);
|
||||
}
|
||||
.drop-space {
|
||||
height: $s-12;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
}
|
||||
.dragging {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: $s-8;
|
||||
background-color: var(--assets-item-background-color-drag);
|
||||
border: $s-2 solid var(--assets-item-border-color-drag);
|
||||
}
|
||||
}
|
257
frontend/src/app/main/ui/workspace/sidebar/assets/common.cljs
Normal file
|
@ -0,0 +1,257 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.assets.common
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.context-menu :refer [context-menu]]
|
||||
[app.main.ui.components.context-menu-a11y :refer [context-menu-a11y]]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.dom.dnd :as dnd]
|
||||
[app.util.strings :refer [matches-search]]
|
||||
[app.util.timers :as ts]
|
||||
[cljs.spec.alpha :as s]
|
||||
[cuerdas.core :as str]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def assets-filters (mf/create-context nil))
|
||||
(def assets-toggle-ordering (mf/create-context nil))
|
||||
(def assets-toggle-list-style (mf/create-context nil))
|
||||
|
||||
(defn apply-filters
|
||||
[coll {:keys [ordering term] :as filters}]
|
||||
(let [reverse? (= :desc ordering)
|
||||
comp-fn (if ^boolean reverse? > <)]
|
||||
(->> coll
|
||||
(filter (fn [item]
|
||||
(or (matches-search (:name item "!$!") term)
|
||||
(matches-search (:value item "!$!") term))))
|
||||
; Sort by folder order, but
|
||||
; putting all "root" items
|
||||
; always first, independently
|
||||
; of sort order.
|
||||
(sort-by #(str/lower (cph/merge-path-item (if (empty? (:path %))
|
||||
(if reverse? "z" "a")
|
||||
(:path %))
|
||||
(:name %)))
|
||||
comp-fn))))
|
||||
|
||||
(defn add-group
|
||||
[asset group-name]
|
||||
(-> (:path asset)
|
||||
(cph/merge-path-item group-name)
|
||||
(cph/merge-path-item (:name asset))))
|
||||
|
||||
(defn rename-group
|
||||
[asset path last-path]
|
||||
(-> (:path asset)
|
||||
(str/slice 0 (count path))
|
||||
(cph/split-path)
|
||||
butlast
|
||||
(vec)
|
||||
(conj last-path)
|
||||
(cph/join-path)
|
||||
(str (str/slice (:path asset) (count path)))
|
||||
(cph/merge-path-item (:name asset))))
|
||||
|
||||
(defn ungroup
|
||||
[asset path]
|
||||
(-> (:path asset)
|
||||
(str/slice 0 (count path))
|
||||
(cph/split-path)
|
||||
butlast
|
||||
(cph/join-path)
|
||||
(str (str/slice (:path asset) (count path)))
|
||||
(cph/merge-path-item (:name asset))))
|
||||
|
||||
(s/def ::asset-name ::us/not-empty-string)
|
||||
(s/def ::name-group-form
|
||||
(s/keys :req-un [::asset-name]))
|
||||
|
||||
(def initial-context-menu-state
|
||||
{:open? false :top nil :left nil})
|
||||
|
||||
(defn open-context-menu
|
||||
[state pos]
|
||||
(let [top (:y pos)
|
||||
left (+ (:x pos) 10)]
|
||||
(assoc state
|
||||
:open? true
|
||||
:top top
|
||||
:left left)))
|
||||
|
||||
(defn close-context-menu
|
||||
[state]
|
||||
(assoc state :open? false))
|
||||
|
||||
(mf/defc assets-context-menu
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [options state on-close]}]
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
(if new-css-system
|
||||
[:& context-menu-a11y
|
||||
{:show (:open? state)
|
||||
:fixed? (or (not= (:top state) 0) (not= (:left state) 0))
|
||||
:on-close on-close
|
||||
:top (:top state)
|
||||
:left (:left state)
|
||||
:options options
|
||||
:workspace? true}]
|
||||
|
||||
[:& context-menu
|
||||
{:selectable false
|
||||
:show (:open? state)
|
||||
:on-close on-close
|
||||
:top (:top state)
|
||||
:left (:left state)
|
||||
:options options}])))
|
||||
|
||||
(mf/defc section-icon
|
||||
[{:keys [section] :as props}]
|
||||
(case section
|
||||
:colors i/drop-refactor
|
||||
:components i/component-refactor
|
||||
:typographies i/text-palette-refactor
|
||||
i/add-refactor))
|
||||
|
||||
(mf/defc asset-section
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [children file-id title section assets-count open?]}]
|
||||
(let [children (->> (if (array? children) children [children])
|
||||
(filter some?))
|
||||
get-role #(.. % -props -role)
|
||||
title-buttons (filter #(= (get-role %) :title-button) children)
|
||||
content (filter #(= (get-role %) :content) children)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)]
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :asset-section) true)}
|
||||
[:& title-bar {:collapsable? true
|
||||
:collapsed? (not open?)
|
||||
:on-collapsed #(st/emit! (dw/set-assets-section-open file-id section (not open?)))
|
||||
:klass :title-spacing
|
||||
:title (mf/html [:span {:class (dom/classnames (css :title-name) true)}
|
||||
[:span {:class (dom/classnames (css :section-icon) true)}
|
||||
[:& section-icon {:section section}]]
|
||||
[:span {:class (dom/classnames (css :section-name) true)}
|
||||
title]
|
||||
|
||||
[:span {:class (dom/classnames (css :num-assets) true)}
|
||||
assets-count]])}
|
||||
title-buttons]
|
||||
(when ^boolean open?
|
||||
content)]
|
||||
[:div.asset-section
|
||||
[:div.asset-title {:class (when (not ^boolean open?) "closed")}
|
||||
[:span {:on-click #(st/emit! (dw/set-assets-section-open file-id section (not open?)))}
|
||||
i/arrow-slide title]
|
||||
[:span.num-assets (dm/str "\u00A0(") assets-count ")"] ;; Unicode 00A0 is non-breaking space
|
||||
title-buttons]
|
||||
(when ^boolean open?
|
||||
content)])))
|
||||
|
||||
(mf/defc asset-section-block
|
||||
[{:keys [children]}]
|
||||
[:* children])
|
||||
|
||||
(defn create-assets-group
|
||||
[rename components-to-group group-name]
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(apply st/emit!
|
||||
(->> components-to-group
|
||||
(map #(rename
|
||||
(:id %)
|
||||
(add-group % group-name)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id))))
|
||||
|
||||
(defn on-drop-asset
|
||||
[event asset dragging* selected selected-full selected-paths rename]
|
||||
(let [create-typed-assets-group (partial create-assets-group rename)]
|
||||
(when (not (dnd/from-child? event))
|
||||
(reset! dragging* false)
|
||||
(when
|
||||
(and (not (contains? selected (:id asset)))
|
||||
(every? #(= % (:path asset)) selected-paths))
|
||||
(let [components-to-group (conj selected-full asset)
|
||||
create-typed-assets-group (partial create-typed-assets-group components-to-group)]
|
||||
(modal/show! :name-group-dialog {:accept create-typed-assets-group}))))))
|
||||
|
||||
(defn on-drag-enter-asset
|
||||
[event asset dragging* selected selected-paths]
|
||||
(when (and
|
||||
(not (dnd/from-child? event))
|
||||
(every? #(= % (:path asset)) selected-paths)
|
||||
(not (contains? selected (:id asset))))
|
||||
(reset! dragging* true)))
|
||||
|
||||
(defn on-drag-leave-asset
|
||||
[event dragging*]
|
||||
(when (not (dnd/from-child? event))
|
||||
(reset! dragging* false)))
|
||||
|
||||
(defn create-counter-element
|
||||
[asset-count]
|
||||
(let [counter-el (dom/create-element "div")]
|
||||
(dom/set-property! counter-el "class" "drag-counter")
|
||||
(dom/set-text! counter-el (str asset-count))
|
||||
counter-el))
|
||||
|
||||
(defn set-drag-image
|
||||
[event item-ref num-selected]
|
||||
(let [offset (dom/get-offset-position (.-nativeEvent event))
|
||||
item-el (mf/ref-val item-ref)
|
||||
counter-el (create-counter-element num-selected)]
|
||||
|
||||
;; set-drag-image requires that the element is rendered and
|
||||
;; visible to the user at the moment of creating the ghost
|
||||
;; image (to make a snapshot), but you may remove it right
|
||||
;; afterwards, in the next render cycle.
|
||||
(dom/append-child! item-el counter-el)
|
||||
(dnd/set-drag-image! event item-el (:x offset) (:y offset))
|
||||
(ts/raf #(.removeChild ^js item-el counter-el))))
|
||||
|
||||
(defn on-asset-drag-start
|
||||
[event file-id asset selected item-ref asset-type on-drag-start]
|
||||
(let [id-asset (:id asset)
|
||||
num-selected (if (contains? selected id-asset)
|
||||
(count selected)
|
||||
1)]
|
||||
(when (not (contains? selected id-asset))
|
||||
(st/emit! (dw/unselect-all-assets file-id)
|
||||
(dw/toggle-selected-assets file-id id-asset asset-type)))
|
||||
(on-drag-start asset event)
|
||||
(when (> num-selected 1)
|
||||
(set-drag-image event item-ref num-selected))))
|
||||
|
||||
(defn on-drag-enter-asset-group
|
||||
[event dragging* prefix selected-paths]
|
||||
(dom/stop-propagation event)
|
||||
(when (and (not (dnd/from-child? event))
|
||||
(not (every? #(= % prefix) selected-paths)))
|
||||
(reset! dragging* true)))
|
||||
|
||||
(defn on-drop-asset-group
|
||||
[event dragging* prefix selected-paths selected-full rename]
|
||||
(dom/stop-propagation event)
|
||||
(when (not (dnd/from-child? event))
|
||||
(reset! dragging* false)
|
||||
(when (not (every? #(= % prefix) selected-paths))
|
||||
(doseq [target-asset selected-full]
|
||||
(st/emit!
|
||||
(rename
|
||||
(:id target-asset)
|
||||
(cph/merge-path-item prefix (:name target-asset))))))))
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"assets_common_button-primary_-eBqD","button-secondary":"assets_common_button-secondary_qo2kg","button-tertiary":"assets_common_button-tertiary_ApdBb","button-tag":"assets_common_button-tag_MHJlj","button-icon":"assets_common_button-icon_0R1zt","button-icon-small":"assets_common_button-icon-small_5kQfO","asset-element":"assets_common_asset-element_frsFR","asset-section":"assets_common_asset-section_uKhc8","title-name":"assets_common_title-name_ZOz9E","section-icon":"assets_common_section-icon_Kitcf","section-name":"assets_common_section-name_RVo-u","num-assets":"assets_common_num-assets_Dguaz"}
|
|
@ -0,0 +1,40 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.asset-section {
|
||||
.title-name {
|
||||
@include tabTitleTipography;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
flex-grow: 1;
|
||||
width: 100%;
|
||||
.section-icon {
|
||||
@include flexCenter;
|
||||
padding-right: $s-8;
|
||||
svg {
|
||||
@include flexCenter;
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
color: transparent;
|
||||
fill: none;
|
||||
}
|
||||
}
|
||||
.section-name {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.num-assets {
|
||||
@include flexCenter;
|
||||
height: 100%;
|
||||
padding-left: $s-8;
|
||||
}
|
||||
}
|
||||
}
|
||||
:global(.title-spacing) {
|
||||
margin-bottom: $s-4;
|
||||
}
|
|
@ -0,0 +1,662 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.assets.components
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.media :as cm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.types.file :as ctf]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.media :as dwm]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.render :refer [component-svg]]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.editable-label :refer [editable-label]]
|
||||
[app.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
[app.main.ui.components.radio-buttons :refer [radio-button radio-buttons]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.dom.dnd :as dnd]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[potok.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(defn- get-component-root-and-container
|
||||
[file-id component components-v2]
|
||||
(if (= file-id (:id @refs/workspace-file))
|
||||
(let [data @refs/workspace-data]
|
||||
[(ctf/get-component-root data component)
|
||||
(if components-v2
|
||||
(ctf/get-component-page data component)
|
||||
component)])
|
||||
(let [data (dm/get-in @refs/workspace-libraries [file-id :data])]
|
||||
[(ctf/get-component-root data component)
|
||||
(if components-v2
|
||||
(ctf/get-component-page data component)
|
||||
component)])))
|
||||
|
||||
(mf/defc components-item
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [component renaming listing-thumbs? selected
|
||||
file-id on-asset-click on-context-menu on-drag-start do-rename
|
||||
cancel-rename selected-full selected-paths]}]
|
||||
(let [item-ref (mf/use-ref)
|
||||
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
component-id (:id component)
|
||||
|
||||
;; NOTE: we don't use reactive deref for it because we don't
|
||||
;; really need rerender on any change on the file change. If
|
||||
;; the component changes, it will trigger rerender anyway.
|
||||
[root-shape container]
|
||||
(get-component-root-and-container file-id component components-v2)
|
||||
|
||||
unselect-all
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (dw/unselect-all-assets))))
|
||||
|
||||
on-component-click
|
||||
(mf/use-fn
|
||||
(mf/deps component selected)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(on-asset-click component-id unselect-all event)))
|
||||
|
||||
on-component-double-click
|
||||
(mf/use-fn
|
||||
(mf/deps file-id component-id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dw/go-to-main-instance file-id component-id))))
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps component dragging* selected selected-full selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset event component dragging* selected selected-full
|
||||
selected-paths dwl/rename-component)))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps component dragging* selected selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset event component dragging* selected selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-component-drag-start
|
||||
(mf/use-fn
|
||||
(mf/deps file-id component selected item-ref on-drag-start read-only?)
|
||||
(fn [event]
|
||||
(if read-only?
|
||||
(dom/prevent-default event)
|
||||
(cmm/on-asset-drag-start event file-id component selected item-ref :components on-drag-start))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps component-id)
|
||||
(partial on-context-menu component-id))]
|
||||
|
||||
(if ^boolean new-css-system
|
||||
[:div {:ref item-ref
|
||||
:class (dom/classnames
|
||||
(css :selected) (contains? selected (:id component))
|
||||
(css :grid-cell) listing-thumbs?
|
||||
(css :enum-item) (not listing-thumbs?))
|
||||
:id (dm/str "component-shape-id-" (:id component))
|
||||
:draggable (not read-only?)
|
||||
:on-click on-component-click
|
||||
:on-double-click on-component-double-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-component-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
(when (and (some? root-shape)
|
||||
(some? container))
|
||||
[:*
|
||||
[:& component-svg {:root-shape root-shape
|
||||
:objects (:objects container)}]
|
||||
(let [renaming? (= renaming (:id component))]
|
||||
[:*
|
||||
[:& editable-label
|
||||
{:class-name (dom/classnames
|
||||
(css :cell-name) listing-thumbs?
|
||||
(css :item-name) (not listing-thumbs?)
|
||||
(css :editing) renaming?)
|
||||
:value (cph/merge-path-item (:path component) (:name component))
|
||||
:tooltip (cph/merge-path-item (:path component) (:name component))
|
||||
:display-value (:name component)
|
||||
:editing? renaming?
|
||||
:disable-dbl-click? true
|
||||
:on-change do-rename
|
||||
:on-cancel cancel-rename}]
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (dom/classnames (css :dragging) true)}])])])]
|
||||
|
||||
[:div {:ref item-ref
|
||||
:class (dom/classnames
|
||||
:selected (contains? selected (:id component))
|
||||
:grid-cell listing-thumbs?
|
||||
:enum-item (not listing-thumbs?))
|
||||
:id (dm/str "component-shape-id-" (:id component))
|
||||
:draggable (not read-only?)
|
||||
:on-click on-component-click
|
||||
:on-double-click on-component-double-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-component-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when (and (some? root-shape)
|
||||
(some? container))
|
||||
[:*
|
||||
[:& component-svg {:root-shape root-shape
|
||||
:objects (:objects container)}]
|
||||
(let [renaming? (= renaming (:id component))]
|
||||
[:*
|
||||
[:& editable-label
|
||||
{:class-name (dom/classnames
|
||||
:cell-name listing-thumbs?
|
||||
:item-name (not listing-thumbs?)
|
||||
:editing renaming?)
|
||||
:value (cph/merge-path-item (:path component) (:name component))
|
||||
:tooltip (cph/merge-path-item (:path component) (:name component))
|
||||
:display-value (:name component)
|
||||
:editing? renaming?
|
||||
:disable-dbl-click? true
|
||||
:on-change do-rename
|
||||
:on-cancel cancel-rename}]
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.dragging])])])])))
|
||||
|
||||
(mf/defc components-group
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file-id prefix groups open-groups renaming listing-thumbs? selected on-asset-click
|
||||
on-drag-start do-rename cancel-rename on-rename-group on-group on-ungroup on-context-menu
|
||||
selected-full]}]
|
||||
|
||||
(let [group-open? (get open-groups prefix true)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
selected-paths (mf/with-memo [selected-full]
|
||||
(into #{}
|
||||
(comp (map :path) (d/nilv ""))
|
||||
selected-full))
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset-group event dragging* prefix selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths selected-full)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full dwl/rename-component)))]
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :component-group) true)
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title
|
||||
{:file-id file-id
|
||||
:section :components
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
|
||||
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [components (get groups "" [])]
|
||||
[:div {:class-name (dom/classnames
|
||||
(css :asset-grid) listing-thumbs?
|
||||
(css :asset-enum) (not listing-thumbs?)
|
||||
(css :drop-space) (and
|
||||
(empty? components)
|
||||
(some? groups)
|
||||
(not dragging?)))
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (dom/classnames (css :grid-placeholder) true)} "\u00A0"])
|
||||
|
||||
|
||||
(when (and (empty? components)
|
||||
(some? groups))
|
||||
[:div {:class (dom/classnames (css :drop-space) true)}])
|
||||
|
||||
(for [component components]
|
||||
[:& components-item
|
||||
{:component component
|
||||
:key (dm/str "component-" (:id component))
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:file-id file-id
|
||||
:selected selected
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths
|
||||
:on-asset-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-drag-start
|
||||
:on-group on-group
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename}])])
|
||||
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& components-group {:file-id file-id
|
||||
:key path-item
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected selected
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]))])]
|
||||
|
||||
|
||||
[:div {:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
[:& grp/asset-group-title
|
||||
{:file-id file-id
|
||||
:section :components
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [components (get groups "" [])]
|
||||
[:div {:class-name (dom/classnames
|
||||
:asset-grid listing-thumbs?
|
||||
:big listing-thumbs?
|
||||
:asset-enum (not listing-thumbs?)
|
||||
:drop-space (and
|
||||
(empty? components)
|
||||
(some? groups)
|
||||
(not dragging?)))
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.grid-placeholder "\u00A0"])
|
||||
|
||||
(when (and (empty? components)
|
||||
(some? groups))
|
||||
[:div.drop-space])
|
||||
|
||||
(for [component components]
|
||||
[:& components-item
|
||||
{:component component
|
||||
:key (dm/str "component-" (:id component))
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:file-id file-id
|
||||
:selected selected
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths
|
||||
:on-asset-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-drag-start
|
||||
:on-group on-group
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename}])])
|
||||
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& components-group {:file-id file-id
|
||||
:key path-item
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected selected
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]))])])))
|
||||
|
||||
(mf/defc components-section
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file-id local? components listing-thumbs? open? reverse-sort? selected
|
||||
on-asset-click on-assets-delete on-clear-selection open-status-ref]}]
|
||||
|
||||
(let [input-ref (mf/use-ref nil)
|
||||
|
||||
state* (mf/use-state {})
|
||||
state (deref state*)
|
||||
|
||||
current-component-id (:component-id state)
|
||||
renaming? (:renaming state)
|
||||
|
||||
open-groups-ref (mf/with-memo [open-status-ref]
|
||||
(-> (l/in [:groups :components])
|
||||
(l/derived open-status-ref)))
|
||||
|
||||
open-groups (mf/deref open-groups-ref)
|
||||
|
||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
toggle-list-style (mf/use-ctx cmm/assets-toggle-list-style)
|
||||
|
||||
selected (:components selected)
|
||||
selected-full (into #{} (filter #(contains? selected (:id %))) components)
|
||||
multi-components? (> (count selected) 1)
|
||||
multi-assets? (or (seq (:graphics selected))
|
||||
(seq (:colors selected))
|
||||
(seq (:typographies selected)))
|
||||
|
||||
groups (mf/with-memo [components reverse-sort?]
|
||||
(grp/group-assets components reverse-sort?))
|
||||
|
||||
add-component
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (dw/set-assets-section-open file-id :components true))
|
||||
(dom/click (mf/ref-val input-ref))))
|
||||
|
||||
on-file-selected
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [blobs]
|
||||
(let [params {:file-id file-id
|
||||
:blobs (seq blobs)}]
|
||||
(st/emit! (dwm/upload-media-components params)
|
||||
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
|
||||
:asset-type "components"})))))
|
||||
|
||||
on-duplicate
|
||||
(mf/use-fn
|
||||
(mf/deps current-component-id selected)
|
||||
(fn []
|
||||
(if (empty? selected)
|
||||
(st/emit! (dwl/duplicate-component file-id current-component-id))
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit! (map (partial dwl/duplicate-component file-id) selected))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
on-delete
|
||||
(mf/use-fn
|
||||
(mf/deps current-component-id file-id multi-components? multi-assets? on-assets-delete)
|
||||
(fn []
|
||||
(let [undo-id (js/Symbol)]
|
||||
(if (or multi-components? multi-assets?)
|
||||
(on-assets-delete)
|
||||
(st/emit! (dwu/start-undo-transaction undo-id)
|
||||
(dwl/delete-component {:id current-component-id})
|
||||
(dwl/sync-file file-id file-id :components current-component-id)
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-fn #(swap! menu-state cmm/close-context-menu))
|
||||
|
||||
on-rename
|
||||
(mf/use-fn #(swap! state* assoc :renaming true))
|
||||
|
||||
cancel-rename
|
||||
(mf/use-fn #(swap! state* dissoc :renaming))
|
||||
|
||||
do-rename
|
||||
(mf/use-fn
|
||||
(mf/deps current-component-id)
|
||||
(fn [new-name]
|
||||
(swap! state* dissoc :renaming)
|
||||
(st/emit!
|
||||
(dwl/rename-component-and-main-instance current-component-id new-name))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps selected on-clear-selection read-only?)
|
||||
(fn [component-id event]
|
||||
(dom/prevent-default event)
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(when (and local? (not read-only?))
|
||||
(when-not (contains? selected component-id)
|
||||
(on-clear-selection))
|
||||
|
||||
(swap! state* assoc :component-id component-id)
|
||||
(swap! menu-state cmm/open-context-menu pos)))))
|
||||
|
||||
create-group
|
||||
(mf/use-fn
|
||||
(mf/deps current-component-id components selected on-clear-selection)
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> components
|
||||
(filter #(if multi-components?
|
||||
(contains? selected (:id %))
|
||||
(= current-component-id (:id %))))
|
||||
(map #(dwl/rename-component
|
||||
(:id %)
|
||||
(cmm/add-group % group-name)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps components)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> components
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/rename-component
|
||||
(:id %)
|
||||
(cmm/rename-group % path last-path)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-group
|
||||
(mf/use-fn
|
||||
(mf/deps components selected create-group)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept create-group})))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps components)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:path path
|
||||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
|
||||
on-ungroup
|
||||
(mf/use-fn
|
||||
(mf/deps components)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> components
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/rename-component (:id %) (cmm/ungroup % path)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-drag-start
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [component event]
|
||||
(dnd/set-data! event "penpot/component" {:file-id file-id
|
||||
:component component})
|
||||
(dnd/set-allowed-effect! event "move")))
|
||||
|
||||
on-show-main
|
||||
(mf/use-fn
|
||||
(mf/deps current-component-id file-id)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dw/go-to-main-instance file-id current-component-id))))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn (mf/deps groups on-asset-click) (partial on-asset-click groups))]
|
||||
|
||||
[:& cmm/asset-section {:file-id file-id
|
||||
:title (tr "workspace.assets.components")
|
||||
:section :components
|
||||
:assets-count (count components)
|
||||
:open? open?}
|
||||
(if ^boolean new-css-system
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
|
||||
(when open?
|
||||
[:div {:class (dom/classnames (css :listing-options) true)}
|
||||
(let [option-selected (if listing-thumbs?
|
||||
"grid"
|
||||
"list")]
|
||||
[:& radio-buttons {:selected option-selected
|
||||
:on-change toggle-list-style
|
||||
:name "listing-style"}
|
||||
[:& radio-button {:icon (mf/html i/view-as-list-refactor)
|
||||
:value "list"
|
||||
:id :list}]
|
||||
[:& radio-button {:icon (mf/html i/flex-grid-refactor)
|
||||
:value "grid"
|
||||
:id :grid}]])])
|
||||
(when (and components-v2 (not read-only?) local?)
|
||||
[:div {:on-click add-component
|
||||
:class (dom/classnames (css :add-component) true)}
|
||||
i/add-refactor
|
||||
[:& file-uploader {:accept cm/str-image-types
|
||||
:multi true
|
||||
:ref input-ref
|
||||
:on-selected on-file-selected}]])]
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when (and components-v2 (not read-only?))
|
||||
[:div.assets-button {:on-click add-component}
|
||||
i/plus
|
||||
[:& file-uploader {:accept cm/str-image-types
|
||||
:multi true
|
||||
:ref input-ref
|
||||
:on-selected on-file-selected}]])]))
|
||||
[:& cmm/asset-section-block {:role :content}
|
||||
[:& components-group {:file-id file-id
|
||||
:prefix ""
|
||||
:groups groups
|
||||
:open-groups open-groups
|
||||
:renaming (when ^boolean renaming? current-component-id)
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected selected
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-group on-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]
|
||||
(when local?
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options (if new-css-system
|
||||
[(when-not (or multi-components? multi-assets?)
|
||||
{:option-name (tr "workspace.assets.rename")
|
||||
:id "assets-rename-component"
|
||||
:option-handler on-rename})
|
||||
(when-not multi-assets?
|
||||
{:option-name (if components-v2
|
||||
(tr "workspace.assets.duplicate-main")
|
||||
(tr "workspace.assets.duplicate"))
|
||||
:id "assets-duplicate-component"
|
||||
:option-handler on-duplicate})
|
||||
|
||||
{:option-name (tr "workspace.assets.delete")
|
||||
:id "assets-delete-component"
|
||||
:option-handler on-delete}
|
||||
(when-not multi-assets?
|
||||
{:option-name (tr "workspace.assets.group")
|
||||
:id "assets-group-component"
|
||||
:option-handler on-group})
|
||||
|
||||
|
||||
(when (and components-v2 (not multi-assets?))
|
||||
{:option-name (tr "workspace.shape.menu.show-main")
|
||||
:id "assets-show-main-component"
|
||||
:option-handler on-show-main})]
|
||||
|
||||
[(when-not (or multi-components? multi-assets?)
|
||||
[(tr "workspace.assets.rename") on-rename])
|
||||
(when-not multi-assets?
|
||||
[(if components-v2
|
||||
(tr "workspace.assets.duplicate-main")
|
||||
(tr "workspace.assets.duplicate")) on-duplicate])
|
||||
[(tr "workspace.assets.delete") on-delete]
|
||||
(when-not multi-assets?
|
||||
[(tr "workspace.assets.group") on-group])
|
||||
(when (and components-v2 (not multi-assets?))
|
||||
[(tr "workspace.shape.menu.show-main") on-show-main])])}])]]))
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"assets_components_button-primary_lsoWq","button-secondary":"assets_components_button-secondary_P8v5X","button-tertiary":"assets_components_button-tertiary_7wMqf","add-component":"assets_components_add-component_X9o2C","button-tag":"assets_components_button-tag_ibmtY","button-icon":"assets_components_button-icon_4Lapr","button-icon-small":"assets_components_button-icon-small_7WrRR","component-group":"assets_components_component-group_AYXVI","asset-enum":"assets_components_asset-enum_iLlfH","enum-item":"assets_components_enum-item_l4zuE","item-name":"assets_components_item-name_Hwadc","editing":"assets_components_editing_3RdZy","asset-grid":"assets_components_asset-grid_mK75F","grid-cell":"assets_components_grid-cell_ctU6T","cell-name":"assets_components_cell-name_DUUMt","asset-element":"assets_components_asset-element_UsbdX","drop-space":"assets_components_drop-space_QhD1-","selected":"assets_components_selected_QLPO7","grid-placeholder":"assets_components_grid-placeholder_a3PoY","listing-options":"assets_components_listing-options_-vPIQ","listing-option-btn":"assets_components_listing-option-btn_-d9cg","first":"assets_components_first_sri1T","dragging":"assets_components_dragging_bWqQC"}
|
|
@ -0,0 +1,249 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.component-group {
|
||||
.drop-space {
|
||||
height: $s-12;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
}
|
||||
.asset-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-auto-rows: calc(10vh + $s-16);
|
||||
gap: $s-4;
|
||||
margin-left: $s-8;
|
||||
margin-right: $s-12;
|
||||
.grid-cell {
|
||||
@include flexCenter;
|
||||
position: relative;
|
||||
padding: $s-8;
|
||||
border: $s-2 solid transparent;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
img {
|
||||
height: auto;
|
||||
width: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
svg {
|
||||
height: 10vh;
|
||||
}
|
||||
.cell-name {
|
||||
@include titleTipography;
|
||||
@include textEllipsis;
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: $s-2;
|
||||
|
||||
&.editing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-32;
|
||||
border: $s-1 solid var(--input-border-color-focus);
|
||||
border-radius: $br-8;
|
||||
background-color: var(--input-background-color);
|
||||
input {
|
||||
@include textEllipsis;
|
||||
@include titleTipography;
|
||||
@include removeInputStyle;
|
||||
flex-grow: 1;
|
||||
height: $s-28;
|
||||
max-width: calc(var(--parent-size) - (var(--depth) * var(--layer-indentation-size)));
|
||||
padding-left: $s-6;
|
||||
margin: 0;
|
||||
border-radius: $br-8;
|
||||
color: var(--input-foreground-color);
|
||||
}
|
||||
span {
|
||||
@include flexCenter;
|
||||
height: $s-28;
|
||||
background-color: transparent;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--input-foreground-color);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
.cell-name {
|
||||
display: block;
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
background: linear-gradient(to top, rgba(52, 57, 59, 1) 0%, rgba(52, 57, 59, 0) 100%);
|
||||
&.editing {
|
||||
display: flex;
|
||||
background: var(--input-background-color);
|
||||
input {
|
||||
color: var(--input-foreground-color-active);
|
||||
}
|
||||
span svg {
|
||||
stroke: var(--input-foreground-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border: $s-1 solid var(--assets-item-border-color);
|
||||
}
|
||||
}
|
||||
.grid-placeholder {
|
||||
width: 100%;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
}
|
||||
}
|
||||
.asset-enum {
|
||||
margin: 0 $s-12;
|
||||
.enum-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-36;
|
||||
margin-bottom: $s-4;
|
||||
padding: $s-2;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
cursor: pointer;
|
||||
|
||||
svg,
|
||||
img {
|
||||
@include flexCenter;
|
||||
padding: $s-2;
|
||||
height: $s-32;
|
||||
width: $s-32;
|
||||
border-radius: $br-6;
|
||||
background-color: var(--assets-item-background-color);
|
||||
}
|
||||
|
||||
.item-name {
|
||||
@include titleTipography;
|
||||
@include textEllipsis;
|
||||
padding-left: $s-8;
|
||||
color: var(--assets-item-name-foreground-color);
|
||||
&.editing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-32;
|
||||
border: $s-1 solid var(--input-border-color-focus);
|
||||
border-radius: $br-8;
|
||||
background-color: var(--input-background-color);
|
||||
input {
|
||||
@include textEllipsis;
|
||||
@include titleTipography;
|
||||
@include removeInputStyle;
|
||||
flex-grow: 1;
|
||||
height: $s-28;
|
||||
max-width: calc(var(--parent-size) - (var(--depth) * var(--layer-indentation-size)));
|
||||
padding-left: $s-6;
|
||||
margin: 0;
|
||||
border-radius: $br-8;
|
||||
color: var(--input-foreground-color);
|
||||
}
|
||||
span {
|
||||
@include flexCenter;
|
||||
height: $s-28;
|
||||
background-color: transparent;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
stroke: var(--input-foreground-color);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
.item-name {
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
&.editing {
|
||||
background: var(--input-background-color);
|
||||
input {
|
||||
color: var(--input-foreground-color-active);
|
||||
}
|
||||
span svg {
|
||||
stroke: var(--input-foreground-color-active);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
border: $s-1 solid var(--assets-item-border-color);
|
||||
}
|
||||
}
|
||||
.grid-placeholder {
|
||||
height: $s-2;
|
||||
width: 100%;
|
||||
background-color: var(--color-accent-primary);
|
||||
}
|
||||
}
|
||||
}
|
||||
.listing-options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.listing-option-btn {
|
||||
@include flexCenter;
|
||||
cursor: pointer;
|
||||
|
||||
&.first {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
svg {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
.add-component {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
margin-left: $s-2;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
:global(.three-row) {
|
||||
.asset-grid {
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
:global(.four-row) {
|
||||
.asset-grid {
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
}
|
||||
}
|
||||
|
||||
.dragging {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: $s-8;
|
||||
background-color: var(--assets-item-background-color-drag);
|
||||
border: $s-2 solid var(--assets-item-border-color-drag);
|
||||
}
|
|
@ -0,0 +1,420 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.assets.file-library
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.libraries :refer [create-file-library-ref]]
|
||||
[app.main.ui.workspace.sidebar.assets.colors :refer [colors-section]]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.sidebar.assets.components :refer [components-section]]
|
||||
[app.main.ui.workspace.sidebar.assets.graphics :refer [graphics-section]]
|
||||
[app.main.ui.workspace.sidebar.assets.typographies :refer [typographies-section]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.router :as rt]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def lens:open-status
|
||||
(l/derived (l/in [:workspace-assets :open-status]) st/state))
|
||||
|
||||
(def lens:selected
|
||||
(-> (l/in [:workspace-assets :selected])
|
||||
(l/derived st/state)))
|
||||
|
||||
(mf/defc file-library-title
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [open? local? shared? project-id file-id page-id file-name]}]
|
||||
(let [router (mf/deref refs/router)
|
||||
url (rt/resolve router :workspace
|
||||
{:project-id project-id
|
||||
:file-id file-id}
|
||||
{:page-id page-id})
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
toggle-open
|
||||
(mf/use-fn
|
||||
(mf/deps file-id open?)
|
||||
(fn []
|
||||
(st/emit! (dw/set-assets-section-open file-id :library (not open?)))))]
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :library-title) true)}
|
||||
[:& title-bar {:collapsable? true
|
||||
:collapsed? (not open?)
|
||||
:on-collapsed toggle-open
|
||||
:title (if local?
|
||||
(mf/html [:div {:class (dom/classnames (css :special-title) true)} (tr "workspace.assets.local-library")
|
||||
[:span {:class (dom/classnames (css :special-subtitle) true)} file-name]])
|
||||
|
||||
(mf/html [:div {:class (dom/classnames (css :special-title) true)} file-name]))}
|
||||
(when-not local?
|
||||
[:span.tool-link.tooltip.tooltip-left {:alt "Open library file"}
|
||||
[:a {:class (dom/classnames (css :file-link) true)
|
||||
:href (str "#" url)
|
||||
:target "_blank"
|
||||
:on-click dom/stop-propagation}
|
||||
i/open-link-refactor]])]]
|
||||
|
||||
[:div.tool-window-bar.library-bar
|
||||
{:on-click toggle-open}
|
||||
[:div.collapse-library
|
||||
{:class (dom/classnames :open open?)}
|
||||
i/arrow-slide]
|
||||
|
||||
(if local?
|
||||
[:*
|
||||
[:span file-name " (" (tr "workspace.assets.local-library") ")"]
|
||||
(when shared?
|
||||
[:span.tool-badge (tr "workspace.assets.shared")])]
|
||||
[:*
|
||||
[:span file-name]
|
||||
[:span.tool-link.tooltip.tooltip-left {:alt "Open library file"}
|
||||
[:a {:href (str "#" url)
|
||||
:target "_blank"
|
||||
:on-click dom/stop-propagation}
|
||||
i/chain]]])])))
|
||||
|
||||
(mf/defc file-library-content
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file local? open-status-ref on-clear-selection]}]
|
||||
(let [components-v2 (mf/use-ctx ctx/components-v2)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
open-status (mf/deref open-status-ref)
|
||||
|
||||
file-id (:id file)
|
||||
project-id (:project-id file)
|
||||
|
||||
filters (mf/use-ctx cmm/assets-filters)
|
||||
filters-section (:section filters)
|
||||
|
||||
filters-term (:term filters)
|
||||
filters-ordering (:ordering filters)
|
||||
filters-list-style (:list-style filters)
|
||||
|
||||
reverse-sort? (= :desc filters-ordering)
|
||||
listing-thumbs? (= :thumbs filters-list-style)
|
||||
|
||||
toggle-ordering (mf/use-ctx cmm/assets-toggle-ordering)
|
||||
toggle-list-style (mf/use-ctx cmm/assets-toggle-list-style)
|
||||
|
||||
library-ref (mf/with-memo [file-id]
|
||||
(create-file-library-ref file-id))
|
||||
|
||||
library (mf/deref library-ref)
|
||||
colors (:colors library)
|
||||
components (:components library)
|
||||
media (:media library)
|
||||
typographies (:typographies library)
|
||||
|
||||
colors (mf/with-memo [filters colors]
|
||||
(cmm/apply-filters colors filters))
|
||||
components (mf/with-memo [filters components]
|
||||
(cmm/apply-filters components filters))
|
||||
media (mf/with-memo [filters media]
|
||||
(cmm/apply-filters media filters))
|
||||
typographies (mf/with-memo [filters typographies]
|
||||
(cmm/apply-filters typographies filters))
|
||||
|
||||
show-components? (and (or (= filters-section "all")
|
||||
(= filters-section "components"))
|
||||
(or (pos? (count components))
|
||||
(str/empty? filters-term)))
|
||||
show-graphics? (and (or (= filters-section "all")
|
||||
(= filters-section "graphics"))
|
||||
(or (pos? (count media))
|
||||
(and (str/empty? filters-term)
|
||||
(not components-v2))))
|
||||
show-colors? (and (or (= filters-section "all")
|
||||
(= filters-section "colors"))
|
||||
(or (> (count colors) 0)
|
||||
(str/empty? filters-term)))
|
||||
show-typography? (and (or (= filters-section "all")
|
||||
(= filters-section "typographies"))
|
||||
(or (pos? (count typographies))
|
||||
(str/empty? filters-term)))
|
||||
|
||||
|
||||
selected-lens (mf/with-memo [file-id]
|
||||
(-> (l/key file-id)
|
||||
(l/derived lens:selected)))
|
||||
|
||||
selected (mf/deref selected-lens)
|
||||
selected-count (+ (count (get selected :components))
|
||||
(count (get selected :graphics))
|
||||
(count (get selected :colors))
|
||||
(count (get selected :typographies)))
|
||||
|
||||
extend-selected
|
||||
(fn [type asset-groups asset-id]
|
||||
(letfn [(flatten-groups [groups]
|
||||
(reduce concat [(get groups "" [])
|
||||
(into []
|
||||
(->> (filter #(seq (first %)) groups)
|
||||
(map second)
|
||||
(mapcat flatten-groups)))]))]
|
||||
|
||||
(let [selected' (get selected type)]
|
||||
(if (zero? (count selected'))
|
||||
(st/emit! (dw/select-single-asset file-id asset-id type))
|
||||
(let [all-assets (flatten-groups asset-groups)
|
||||
click-index (d/index-of-pred all-assets #(= (:id %) asset-id))
|
||||
first-index (->> (get selected type)
|
||||
(map (fn [asset] (d/index-of-pred all-assets #(= (:id %) asset))))
|
||||
(sort)
|
||||
(first))
|
||||
|
||||
min-index (min first-index click-index)
|
||||
max-index (max first-index click-index)
|
||||
ids (->> (d/enumerate all-assets)
|
||||
(into #{} (comp (filter #(<= min-index (first %) max-index))
|
||||
(map (comp :id second)))))]
|
||||
|
||||
(st/emit! (dw/select-assets file-id ids type)))))))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn
|
||||
(mf/deps file-id extend-selected)
|
||||
(fn [asset-type asset-groups asset-id default-click event]
|
||||
(cond
|
||||
(kbd/mod? event)
|
||||
(do
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dw/toggle-selected-assets file-id asset-id asset-type)))
|
||||
|
||||
(kbd/shift? event)
|
||||
(do
|
||||
(dom/stop-propagation event)
|
||||
(extend-selected asset-type asset-groups asset-id))
|
||||
|
||||
:else
|
||||
(when default-click
|
||||
(default-click event)))))
|
||||
|
||||
on-component-click
|
||||
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :components))
|
||||
|
||||
on-graphics-click
|
||||
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :graphics))
|
||||
|
||||
on-colors-click
|
||||
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :colors))
|
||||
|
||||
on-typography-click
|
||||
(mf/use-fn (mf/deps on-asset-click) (partial on-asset-click :typographies))
|
||||
|
||||
on-assets-delete
|
||||
(mf/use-fn
|
||||
(mf/deps selected file-id)
|
||||
(fn []
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit! (map #(dwl/delete-component {:id %})
|
||||
(:components selected)))
|
||||
(run! st/emit! (map #(dwl/delete-media {:id %})
|
||||
(:graphics selected)))
|
||||
(run! st/emit! (map #(dwl/delete-color {:id %})
|
||||
(:colors selected)))
|
||||
(run! st/emit! (map #(dwl/delete-typography %)
|
||||
(:typographies selected)))
|
||||
|
||||
(when (or (seq (:components selected))
|
||||
(seq (:colors selected))
|
||||
(seq (:typographies selected)))
|
||||
(st/emit! (dwl/sync-file file-id file-id)))
|
||||
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))]
|
||||
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :library-content) true)}
|
||||
(when ^boolean show-components?
|
||||
[:& components-section
|
||||
{:file-id file-id
|
||||
:local? local?
|
||||
:components components
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:open? (get open-status :components true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-component-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when ^boolean show-graphics?
|
||||
[:& graphics-section
|
||||
{:file-id file-id
|
||||
:project-id project-id
|
||||
:local? local?
|
||||
:objects media
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:open? (get open-status :graphics true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-graphics-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when ^boolean show-colors?
|
||||
[:& colors-section
|
||||
{:file-id file-id
|
||||
:local? local?
|
||||
:colors colors
|
||||
:open? (get open-status :colors true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-colors-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when ^boolean show-typography?
|
||||
[:& typographies-section
|
||||
{:file file
|
||||
:file-id (:id file)
|
||||
:local? local?
|
||||
:typographies typographies
|
||||
:open? (get open-status :typographies true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-typography-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when (and (not ^boolean show-components?)
|
||||
(not ^boolean show-graphics?)
|
||||
(not ^boolean show-colors?)
|
||||
(not ^boolean show-typography?))
|
||||
[:div {:class (css :asset-title)} (tr "workspace.assets.not-found")])]
|
||||
|
||||
[:div.tool-window-content
|
||||
[:div.listing-options
|
||||
(when (> selected-count 0)
|
||||
[:span.selected-count
|
||||
(tr "workspace.assets.selected-count" (i18n/c selected-count))])
|
||||
[:div.listing-option-btn.first {:on-click toggle-ordering}
|
||||
(if reverse-sort?
|
||||
i/sort-ascending
|
||||
i/sort-descending)]
|
||||
[:div.listing-option-btn {:on-click toggle-list-style}
|
||||
(if listing-thumbs?
|
||||
i/listing-enum
|
||||
i/listing-thumbs)]]
|
||||
|
||||
(when ^boolean show-components?
|
||||
[:& components-section
|
||||
{:file-id file-id
|
||||
:local? local?
|
||||
:components components
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:open? (get open-status :components true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-component-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when ^boolean show-graphics?
|
||||
[:& graphics-section
|
||||
{:file-id file-id
|
||||
:project-id project-id
|
||||
:local? local?
|
||||
:objects media
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:open? (get open-status :graphics true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-graphics-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when ^boolean show-colors?
|
||||
[:& colors-section
|
||||
{:file-id file-id
|
||||
:local? local?
|
||||
:colors colors
|
||||
:open? (get open-status :colors true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-colors-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when ^boolean show-typography?
|
||||
[:& typographies-section
|
||||
{:file file
|
||||
:file-id (:id file)
|
||||
:local? local?
|
||||
:typographies typographies
|
||||
:open? (get open-status :typographies true)
|
||||
:open-status-ref open-status-ref
|
||||
:reverse-sort? reverse-sort?
|
||||
:selected selected
|
||||
:on-asset-click on-typography-click
|
||||
:on-assets-delete on-assets-delete
|
||||
:on-clear-selection on-clear-selection}])
|
||||
|
||||
(when (and (not ^boolean show-components?)
|
||||
(not ^boolean show-graphics?)
|
||||
(not ^boolean show-colors?)
|
||||
(not ^boolean show-typography?))
|
||||
[:div.asset-section
|
||||
[:div.asset-title (tr "workspace.assets.not-found")]])])))
|
||||
|
||||
(mf/defc file-library
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file local? default-open? filters]}]
|
||||
(let [file-id (:id file)
|
||||
file-name (:name file)
|
||||
shared? (:is-shared file)
|
||||
project-id (:project-id file)
|
||||
page-id (dm/get-in file [:data :pages 0])
|
||||
|
||||
open-status-ref (mf/with-memo [file-id]
|
||||
(-> (l/key file-id)
|
||||
(l/derived lens:open-status)))
|
||||
open-status (mf/deref open-status-ref)
|
||||
open? (d/nilv (:library open-status) default-open?)
|
||||
|
||||
unselect-all
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn []
|
||||
(st/emit! (dw/unselect-all-assets file-id))))]
|
||||
|
||||
[:div.tool-window {:on-context-menu dom/prevent-default
|
||||
:on-click unselect-all}
|
||||
[:& file-library-title
|
||||
{:project-id project-id
|
||||
:file-id file-id
|
||||
:page-id page-id
|
||||
:file-name file-name
|
||||
:open? open?
|
||||
:local? local?
|
||||
:shared? shared?}]
|
||||
(when ^boolean open?
|
||||
[:& file-library-content
|
||||
{:file file
|
||||
:local? local?
|
||||
:filters filters
|
||||
:on-clear-selection unselect-all
|
||||
:open-status-ref open-status-ref}])]))
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"assets_file_library_button-primary_o8czr","button-secondary":"assets_file_library_button-secondary_BCBmw","button-tertiary":"assets_file_library_button-tertiary_JiCQn","library-title":"assets_file_library_library-title_FvGs6","file-link":"assets_file_library_file-link_CtN0K","button-tag":"assets_file_library_button-tag_cyg7Q","button-icon":"assets_file_library_button-icon_R-4R0","button-icon-small":"assets_file_library_button-icon-small_9UOdy","asset-element":"assets_file_library_asset-element_6ian7","file-name":"assets_file_library_file-name_Pc8ng","special-title":"assets_file_library_special-title_-Pqzq","special-subtitle":"assets_file_library_special-subtitle_9xOl9","library-content":"assets_file_library_library-content_Yto-8","asset-title":"assets_file_library_asset-title_ozD8M"}
|
|
@ -0,0 +1,51 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.library-title {
|
||||
.file-name {
|
||||
@include titleTipography;
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
align-items: center;
|
||||
flex-grow: 100;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.special-title {
|
||||
color: var(--title-foreground-color-hover);
|
||||
}
|
||||
.special-subtitle {
|
||||
padding-left: $s-4;
|
||||
color: var(--title-foreground-color);
|
||||
text-transform: initial;
|
||||
}
|
||||
.file-link {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
margin-right: $s-12;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon-small;
|
||||
fill: var(--title-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
}
|
||||
.library-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.asset-title {
|
||||
@include titleTipography;
|
||||
margin-left: $s-28;
|
||||
}
|
553
frontend/src/app/main/ui/workspace/sidebar/assets/graphics.cljs
Normal file
|
@ -0,0 +1,553 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.assets.graphics
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.media :as cm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.config :as cf]
|
||||
[app.main.data.events :as ev]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.media :as dwm]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.editable-label :refer [editable-label]]
|
||||
[app.main.ui.components.file-uploader :refer [file-uploader]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.hooks :as h]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.dom.dnd :as dnd]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[potok.core :as ptk]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc graphics-item
|
||||
[{:keys [object renaming listing-thumbs? selected-objects file-id
|
||||
on-asset-click on-context-menu on-drag-start do-rename cancel-rename
|
||||
selected-full selected-graphics-paths]}]
|
||||
(let [item-ref (mf/use-ref)
|
||||
visible? (h/use-visible item-ref :once? true)
|
||||
object-id (:id object)
|
||||
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps object dragging* selected-objects selected-full selected-graphics-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset event object dragging* selected-objects selected-full
|
||||
selected-graphics-paths dwl/rename-media)))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps object dragging* selected-objects selected-graphics-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset event object dragging* selected-objects selected-graphics-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-grahic-drag-start
|
||||
(mf/use-fn
|
||||
(mf/deps object file-id selected-objects item-ref on-drag-start read-only?)
|
||||
(fn [event]
|
||||
(if read-only?
|
||||
(dom/prevent-default event)
|
||||
(cmm/on-asset-drag-start event file-id object selected-objects item-ref :graphics on-drag-start))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps object-id)
|
||||
(partial on-context-menu object-id))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn
|
||||
(mf/deps object-id on-asset-click)
|
||||
(partial on-asset-click object-id nil))]
|
||||
(if ^boolean new-css-system
|
||||
[:div {:ref item-ref
|
||||
:class-name (dom/classnames
|
||||
(css :selected) (contains? selected-objects object-id)
|
||||
(css :grid-cell) listing-thumbs?
|
||||
(css :enum-item) (not listing-thumbs?))
|
||||
:draggable (not read-only?)
|
||||
:on-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-grahic-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when visible?
|
||||
[:*
|
||||
[:img {:src (when visible? (cf/resolve-file-media object true))
|
||||
:class (css :graphic-image)
|
||||
:draggable false}] ;; Also need to add css pointer-events: none
|
||||
|
||||
(let [renaming? (= renaming (:id object))]
|
||||
[:*
|
||||
[:& editable-label
|
||||
{:class-name (dom/classnames
|
||||
(css :cell-name) listing-thumbs?
|
||||
(css :item-name) (not listing-thumbs?)
|
||||
(css :editing) renaming?)
|
||||
:value (cph/merge-path-item (:path object) (:name object))
|
||||
:tooltip (cph/merge-path-item (:path object) (:name object))
|
||||
:display-value (:name object)
|
||||
:editing? renaming?
|
||||
:disable-dbl-click? true
|
||||
:on-change do-rename
|
||||
:on-cancel cancel-rename}]
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (dom/classnames (css :dragging) true)}])])])]
|
||||
|
||||
[:div {:ref item-ref
|
||||
:class-name (dom/classnames
|
||||
:selected (contains? selected-objects object-id)
|
||||
:grid-cell listing-thumbs?
|
||||
:enum-item (not listing-thumbs?))
|
||||
:draggable (not read-only?)
|
||||
:on-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-grahic-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when visible?
|
||||
[:*
|
||||
[:img {:src (when visible? (cf/resolve-file-media object true))
|
||||
:draggable false}] ;; Also need to add css pointer-events: none
|
||||
|
||||
(let [renaming? (= renaming (:id object))]
|
||||
[:*
|
||||
[:& editable-label
|
||||
{:class-name (dom/classnames
|
||||
:cell-name listing-thumbs?
|
||||
:item-name (not listing-thumbs?)
|
||||
:editing renaming?)
|
||||
:value (cph/merge-path-item (:path object) (:name object))
|
||||
:tooltip (cph/merge-path-item (:path object) (:name object))
|
||||
:display-value (:name object)
|
||||
:editing? renaming?
|
||||
:disable-dbl-click? true
|
||||
:on-change do-rename
|
||||
:on-cancel cancel-rename}]
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.dragging])])])])))
|
||||
|
||||
(mf/defc graphics-group
|
||||
[{:keys [file-id prefix groups open-groups renaming listing-thumbs? selected-objects on-asset-click
|
||||
on-drag-start do-rename cancel-rename on-rename-group on-ungroup
|
||||
on-context-menu selected-full]}]
|
||||
(let [group-open? (get open-groups prefix true)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
selected-paths
|
||||
(mf/with-memo [selected-full]
|
||||
(into #{}
|
||||
(comp (map :path) (d/nilv ""))
|
||||
selected-full))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset-group event dragging* prefix selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths selected-full)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full dwl/rename-media)))]
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :graphics-group) true)
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title
|
||||
{:file-id file-id
|
||||
:section :graphics
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [objects (get groups "" [])]
|
||||
[:div {:class-name (dom/classnames
|
||||
(css :asset-grid) listing-thumbs?
|
||||
(css :asset-enum) (not listing-thumbs?)
|
||||
(css :drop-space) (and
|
||||
(empty? objects)
|
||||
(some? groups)
|
||||
(not dragging?)))
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (dom/classnames (css :grid-placeholder) true)} "\u00A0"])
|
||||
|
||||
(when (and (empty? objects)
|
||||
(some? groups))
|
||||
[:div {:class (dom/classnames (css :drop-space) true)}])
|
||||
|
||||
(for [object objects]
|
||||
[:& graphics-item
|
||||
{:key (dm/str "object-" (:id object))
|
||||
:file-id file-id
|
||||
:object object
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected-objects selected-objects
|
||||
:on-asset-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths}])])
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& graphics-group {:file-id file-id
|
||||
:key path-item
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected-objects selected-objects
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths}]))])]
|
||||
|
||||
[:div {:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title {:file-id file-id
|
||||
:section :graphics
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [objects (get groups "" [])]
|
||||
[:div {:class-name (dom/classnames
|
||||
:asset-grid listing-thumbs?
|
||||
:asset-enum (not listing-thumbs?)
|
||||
:drop-space (and
|
||||
(empty? objects)
|
||||
(some? groups)
|
||||
(not dragging?)))
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.grid-placeholder "\u00A0"])
|
||||
|
||||
(when (and (empty? objects)
|
||||
(some? groups))
|
||||
[:div.drop-space])
|
||||
|
||||
(for [object objects]
|
||||
[:& graphics-item {:key (dm/str "object-" (:id object))
|
||||
:file-id file-id
|
||||
:object object
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected-objects selected-objects
|
||||
:on-asset-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths}])])
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& graphics-group {:file-id file-id
|
||||
:key path-item
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:renaming renaming
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected-objects selected-objects
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths}]))])])))
|
||||
|
||||
(mf/defc graphics-section
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file-id project-id local? objects listing-thumbs? open? open-status-ref selected reverse-sort?
|
||||
on-asset-click on-assets-delete on-clear-selection]}]
|
||||
(let [input-ref (mf/use-ref nil)
|
||||
state (mf/use-state {:renaming nil :object-id nil})
|
||||
|
||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
|
||||
open-groups-ref (mf/with-memo [open-status-ref]
|
||||
(-> (l/in [:groups :graphics])
|
||||
(l/derived open-status-ref)))
|
||||
open-groups (mf/deref open-groups-ref)
|
||||
|
||||
selected (:graphics selected)
|
||||
selected-full (into #{} (filter #(contains? selected (:id %))) objects)
|
||||
multi-objects? (> (count selected) 1)
|
||||
multi-assets? (or (seq (:components selected))
|
||||
(seq (:colors selected))
|
||||
(seq (:typographies selected)))
|
||||
|
||||
objects (mf/with-memo [objects]
|
||||
(mapv dwl/extract-path-if-missing objects))
|
||||
|
||||
groups (mf/with-memo [objects reverse-sort?]
|
||||
(grp/group-assets objects reverse-sort?))
|
||||
|
||||
components-v2 (mf/use-ctx ctx/components-v2)
|
||||
team-id (mf/use-ctx ctx/current-team-id)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
|
||||
add-graphic
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(st/emit! (dw/set-assets-section-open file-id :graphics true))
|
||||
(dom/click (mf/ref-val input-ref))))
|
||||
|
||||
on-file-selected
|
||||
(mf/use-fn
|
||||
(mf/deps file-id project-id team-id)
|
||||
(fn [blobs]
|
||||
(let [params {:file-id file-id
|
||||
:blobs (seq blobs)}]
|
||||
(st/emit! (dwm/upload-media-asset params)
|
||||
(ptk/event ::ev/event {::ev/name "add-asset-to-library"
|
||||
:asset-type "graphics"
|
||||
:file-id file-id
|
||||
:project-id project-id
|
||||
:team-id team-id})))))
|
||||
on-delete
|
||||
(mf/use-fn
|
||||
(mf/deps @state multi-objects? multi-assets?)
|
||||
(fn []
|
||||
(if (or multi-objects? multi-assets?)
|
||||
(on-assets-delete)
|
||||
(st/emit! (dwl/delete-media {:id (:object-id @state)})))))
|
||||
|
||||
on-rename
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! state (fn [state]
|
||||
(assoc state :renaming (:component-id state))))))
|
||||
cancel-rename
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
do-rename
|
||||
(mf/use-fn
|
||||
(mf/deps @state)
|
||||
(fn [new-name]
|
||||
(st/emit! (dwl/rename-media (:renaming @state) new-name))
|
||||
(swap! state assoc :renaming nil)))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps selected on-clear-selection read-only?)
|
||||
(fn [object-id event]
|
||||
(dom/prevent-default event)
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(when (and local? (not read-only?))
|
||||
(when-not (contains? selected object-id)
|
||||
(on-clear-selection))
|
||||
(swap! state assoc :object-id object-id)
|
||||
(swap! menu-state cmm/open-context-menu pos)))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state cmm/close-context-menu)))
|
||||
|
||||
create-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects selected on-clear-selection (:object-id @state))
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> objects
|
||||
(filter #(if multi-objects?
|
||||
(contains? selected (:id %))
|
||||
(= (:object-id @state) (:id %))))
|
||||
(map #(dwl/rename-media (:id %) (cmm/add-group % group-name)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> objects
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/rename-media (:id %) (cmm/rename-group % path last-path)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects selected create-group)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept create-group})))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:path path
|
||||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
on-ungroup
|
||||
(mf/use-fn
|
||||
(mf/deps objects)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> objects
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/rename-media (:id %) (cmm/ungroup % path)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-drag-start
|
||||
(mf/use-fn
|
||||
(fn [{:keys [name id mtype]} event]
|
||||
(dnd/set-data! event "text/asset-id" (str id))
|
||||
(dnd/set-data! event "text/asset-name" name)
|
||||
(dnd/set-data! event "text/asset-type" mtype)
|
||||
(dnd/set-allowed-effect! event "move")))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn (mf/deps groups on-asset-click) (partial on-asset-click groups))]
|
||||
|
||||
[:& cmm/asset-section {:file-id file-id
|
||||
:title (tr "workspace.assets.graphics")
|
||||
:section :graphics
|
||||
:assets-count (count objects)
|
||||
:open? open?}
|
||||
(if new-css-system
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when (and (not components-v2) (not read-only?))
|
||||
[:button {:class (dom/classnames (css :assets-btn) true)
|
||||
:on-click add-graphic}
|
||||
i/add-refactor
|
||||
[:& file-uploader {:accept cm/str-image-types
|
||||
:multi true
|
||||
:ref input-ref
|
||||
:on-selected on-file-selected}]])])
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when (and (not components-v2) (not read-only?))
|
||||
[:div.assets-button {:on-click add-graphic}
|
||||
i/plus
|
||||
[:& file-uploader {:accept cm/str-image-types
|
||||
:multi true
|
||||
:ref input-ref
|
||||
:on-selected on-file-selected}]])]))
|
||||
|
||||
[:& cmm/asset-section-block {:role :content}
|
||||
[:& graphics-group {:file-id file-id
|
||||
:prefix ""
|
||||
:groups groups
|
||||
:open-groups open-groups
|
||||
:renaming (:renaming @state)
|
||||
:listing-thumbs? listing-thumbs?
|
||||
:selected selected
|
||||
:on-asset-click on-asset-click
|
||||
:on-drag-start on-drag-start
|
||||
:do-rename do-rename
|
||||
:cancel-rename cancel-rename
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]
|
||||
(when local?
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options (if new-css-system
|
||||
[(when-not (or multi-objects? multi-assets?)
|
||||
{:option-name (tr "workspace.assets.rename")
|
||||
:id "assets-rename-graphics"
|
||||
:option-handler on-rename})
|
||||
{:option-name (tr "workspace.assets.delete")
|
||||
:id "assets-delete-graphics"
|
||||
:option-handler on-delete}
|
||||
(when-not multi-assets?
|
||||
{:option-name (tr "workspace.assets.group")
|
||||
:id "assets-group-graphics"
|
||||
:option-handler on-group})]
|
||||
|
||||
[(when-not (or multi-objects? multi-assets?)
|
||||
[(tr "workspace.assets.rename") on-rename])
|
||||
[(tr "workspace.assets.delete") on-delete]
|
||||
(when-not multi-assets?
|
||||
[(tr "workspace.assets.group") on-group])])}])]]))
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"assets_graphics_button-primary_6qIO6","button-secondary":"assets_graphics_button-secondary_0qkG4","button-tertiary":"assets_graphics_button-tertiary_bWZ1s","assets-btn":"assets_graphics_assets-btn_BIoeo","add-component":"assets_graphics_add-component_bgwrr","button-tag":"assets_graphics_button-tag_K3ckf","button-icon":"assets_graphics_button-icon_En5qq","button-icon-small":"assets_graphics_button-icon-small_xNHzC","asset-element":"assets_graphics_asset-element_-VwmF","graphics-group":"assets_graphics_graphics-group_kibPf","drop-space":"assets_graphics_drop-space_2UAKf","asset-grid":"assets_graphics_asset-grid_6ET0K","grid-cell":"assets_graphics_grid-cell_EHW4x","cell-name":"assets_graphics_cell-name_JgbUS","editing":"assets_graphics_editing_O-Ozt","editable-label-input":"assets_graphics_editable-label-input_Yc2zA","editable-label-close":"assets_graphics_editable-label-close_16VT8","selected":"assets_graphics_selected_Q9YJC","dragging":"assets_graphics_dragging_oVA41","asset-enum":"assets_graphics_asset-enum_TS6Je","enum-item":"assets_graphics_enum-item_UFh4c","item-name":"assets_graphics_item-name_HGIQs","grid-placeholder":"assets_graphics_grid-placeholder_9brkO","listing-options":"assets_graphics_listing-options_Jw51P","listing-option-btn":"assets_graphics_listing-option-btn_3IkTO","first":"assets_graphics_first_kU3zf"}
|
190
frontend/src/app/main/ui/workspace/sidebar/assets/graphics.scss
Normal file
|
@ -0,0 +1,190 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.graphics-group {
|
||||
.drop-space {
|
||||
height: $s-12;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
}
|
||||
.asset-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: $s-4;
|
||||
margin-left: $s-8;
|
||||
margin-right: $s-12;
|
||||
.grid-cell {
|
||||
@include flexCenter;
|
||||
position: relative;
|
||||
padding: $s-8;
|
||||
border: $s-2 solid transparent;
|
||||
border-radius: $br-8;
|
||||
aspect-ratio: 1/1;
|
||||
background-color: var(--assets-item-background-color);
|
||||
overflow: hidden;
|
||||
cursor: pointer;
|
||||
img {
|
||||
height: auto;
|
||||
width: auto;
|
||||
max-height: 100%;
|
||||
max-width: 100%;
|
||||
pointer-events: none;
|
||||
}
|
||||
svg {
|
||||
height: 10vh;
|
||||
}
|
||||
.cell-name {
|
||||
@include titleTipography;
|
||||
@include textEllipsis;
|
||||
display: none;
|
||||
position: absolute;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
width: 100%;
|
||||
padding: $s-2;
|
||||
|
||||
&.editing {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.editable-label-input {
|
||||
height: unset;
|
||||
width: 100%;
|
||||
padding: $s-2;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.editable-label-close {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
.cell-name {
|
||||
display: block;
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
background: linear-gradient(to top, rgba(52, 57, 59, 1) 0%, rgba(52, 57, 59, 0) 100%);
|
||||
}
|
||||
}
|
||||
|
||||
&.selected {
|
||||
border: $s-1 solid var(--assets-item-border-color);
|
||||
}
|
||||
|
||||
.dragging {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
border-radius: $s-8;
|
||||
background-color: var(--assets-item-background-color-drag);
|
||||
border: $s-2 solid var(--assets-item-border-color-drag);
|
||||
}
|
||||
}
|
||||
}
|
||||
.asset-enum {
|
||||
margin: 0 $s-12;
|
||||
|
||||
.enum-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: $s-36;
|
||||
margin-bottom: $s-4;
|
||||
padding: $s-2;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
cursor: pointer;
|
||||
|
||||
svg,
|
||||
img {
|
||||
@include flexCenter;
|
||||
padding: $s-2;
|
||||
height: $s-32;
|
||||
width: $s-32;
|
||||
border-radius: $br-6;
|
||||
background-color: var(--assets-component-background-color);
|
||||
}
|
||||
|
||||
.item-name {
|
||||
@include titleTipography;
|
||||
@include textEllipsis;
|
||||
padding-left: $s-8;
|
||||
color: var(--assets-item-name-foreground-color);
|
||||
|
||||
&.editing {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.editable-label-input {
|
||||
height: $s-24;
|
||||
}
|
||||
|
||||
.editable-label-close {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
&:hover {
|
||||
background-color: var(--assets-item-background-color-hover);
|
||||
.item-name {
|
||||
color: var(--assets-item-name-foreground-color-hover);
|
||||
}
|
||||
}
|
||||
&.selected {
|
||||
border: $s-1 solid var(--assets-item-border-color);
|
||||
}
|
||||
}
|
||||
}
|
||||
.grid-placeholder {
|
||||
height: $s-2;
|
||||
background-color: var(--color-accent-primary);
|
||||
margin-bottom: $s-2;
|
||||
}
|
||||
}
|
||||
.listing-options {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.listing-option-btn {
|
||||
@include flexCenter;
|
||||
cursor: pointer;
|
||||
|
||||
&.first {
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
svg {
|
||||
height: $s-16;
|
||||
width: $s-16;
|
||||
}
|
||||
}
|
||||
}
|
||||
.add-component {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: $s-28;
|
||||
margin-left: $s-2;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
|
||||
.assets-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: calc($s-24 + $s-4);
|
||||
padding: 0;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
171
frontend/src/app/main/ui/workspace/sidebar/assets/groups.cljs
Normal file
|
@ -0,0 +1,171 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.assets.groups
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.common.spec :as us]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace :as dw]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.components.forms :as fm]
|
||||
[app.main.ui.components.title-bar :refer [title-bar]]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cljs.spec.alpha :as s]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc asset-group-title
|
||||
[{:keys [file-id section path group-open? on-rename on-ungroup]}]
|
||||
(when-not (empty? path)
|
||||
(let [[other-path last-path truncated] (cph/compact-path path 35 true)
|
||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
on-fold-group
|
||||
(mf/use-fn
|
||||
(mf/deps file-id section path group-open?)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(st/emit! (dw/set-assets-group-open file-id
|
||||
section
|
||||
path
|
||||
(not group-open?)))))
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(dom/prevent-default event)
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(swap! menu-state cmm/open-context-menu pos))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-fn #(swap! menu-state cmm/close-context-menu))]
|
||||
(if new-css-system
|
||||
[:div {:class (dom/classnames (css :group-title) true)
|
||||
:on-context-menu on-context-menu}
|
||||
[:& title-bar {:collapsable? true
|
||||
:collapsed? (not group-open?)
|
||||
:on-collapsed on-fold-group
|
||||
:title (mf/html [:* (when-not (empty? other-path)
|
||||
[:span {:class (dom/classnames (css :pre-path) true)
|
||||
:title (when truncated path)}
|
||||
other-path "\u00A0\u2022\u00A0"])
|
||||
[:span {:class (dom/classnames (css :path) true)
|
||||
:title (when truncated path)}
|
||||
last-path]])}]
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options [{:option-name (tr "workspace.assets.rename")
|
||||
:id "assets-rename-group"
|
||||
:option-handler #(on-rename % path last-path)}
|
||||
{:option-name (tr "workspace.assets.ungroup")
|
||||
:id "assets-ungroup-group"
|
||||
:option-handler #(on-ungroup path)}]}]]
|
||||
|
||||
|
||||
[:div.group-title {:class (when-not group-open? "closed")
|
||||
:on-click on-fold-group
|
||||
:on-context-menu on-context-menu}
|
||||
[:span i/arrow-slide]
|
||||
(when-not (empty? other-path)
|
||||
[:span.dim {:title (when truncated path)}
|
||||
other-path "\u00A0/\u00A0"])
|
||||
[:span {:title (when truncated path)}
|
||||
last-path]
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options [[(tr "workspace.assets.rename") #(on-rename % path last-path)]
|
||||
[(tr "workspace.assets.ungroup") #(on-ungroup path)]]}]]))))
|
||||
|
||||
(defn group-assets
|
||||
"Convert a list of assets in a nested structure like this:
|
||||
|
||||
{'': [{assetA} {assetB}]
|
||||
'group1': {'': [{asset1A} {asset1B}]
|
||||
'subgroup11': {'': [{asset11A} {asset11B} {asset11C}]}
|
||||
'subgroup12': {'': [{asset12A}]}}
|
||||
'group2': {'subgroup21': {'': [{asset21A}}}}
|
||||
"
|
||||
[assets reverse-sort?]
|
||||
(when-not (empty? assets)
|
||||
(reduce (fn [groups {:keys [path] :as asset}]
|
||||
(let [path (cph/split-path (or path ""))]
|
||||
(update-in groups
|
||||
(conj path "")
|
||||
(fn [group]
|
||||
(if group
|
||||
(conj group asset)
|
||||
[asset])))))
|
||||
(sorted-map-by (fn [key1 key2]
|
||||
(if reverse-sort?
|
||||
(compare key2 key1)
|
||||
(compare key1 key2))))
|
||||
assets)))
|
||||
|
||||
(s/def ::asset-name ::us/not-empty-string)
|
||||
(s/def ::name-group-form
|
||||
(s/keys :req-un [::asset-name]))
|
||||
|
||||
(mf/defc name-group-dialog
|
||||
{::mf/register modal/components
|
||||
::mf/register-as :name-group-dialog}
|
||||
[{:keys [path last-path accept] :as ctx
|
||||
:or {path "" last-path ""}}]
|
||||
(let [initial (mf/use-memo
|
||||
(mf/deps last-path)
|
||||
(constantly {:asset-name last-path}))
|
||||
form (fm/use-form :spec ::name-group-form
|
||||
:initial initial)
|
||||
|
||||
create? (empty? path)
|
||||
|
||||
on-close (mf/use-fn #(modal/hide!))
|
||||
|
||||
on-accept
|
||||
(mf/use-fn
|
||||
(mf/deps form)
|
||||
(fn [_]
|
||||
(let [asset-name (get-in @form [:clean-data :asset-name])]
|
||||
(if create?
|
||||
(accept asset-name)
|
||||
(accept path asset-name))
|
||||
(modal/hide!))))]
|
||||
|
||||
[:div.modal-overlay
|
||||
[:div.modal-container.confirm-dialog
|
||||
[:div.modal-header
|
||||
[:div.modal-header-title
|
||||
[:h2 (if create?
|
||||
(tr "workspace.assets.create-group")
|
||||
(tr "workspace.assets.rename-group"))]]
|
||||
[:div.modal-close-button
|
||||
{:on-click on-close} i/close]]
|
||||
|
||||
[:div.modal-content.generic-form
|
||||
[:& fm/form {:form form :on-submit on-accept}
|
||||
[:& fm/input {:name :asset-name
|
||||
:auto-focus? true
|
||||
:label (tr "workspace.assets.group-name")
|
||||
:hint (tr "workspace.assets.create-group-hint")}]]]
|
||||
|
||||
[:div.modal-footer
|
||||
[:div.action-buttons
|
||||
[:input.cancel-button
|
||||
{:type "button"
|
||||
:value (tr "labels.cancel")
|
||||
:on-click on-close}]
|
||||
|
||||
[:input.accept-button.primary
|
||||
{:type "button"
|
||||
:class (when-not (:valid @form) "btn-disabled")
|
||||
:disabled (not (:valid @form))
|
||||
:value (if create? (tr "labels.create") (tr "labels.rename"))
|
||||
:on-click on-accept}]]]]]))
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"assets_groups_button-primary_2o3Db","button-secondary":"assets_groups_button-secondary_-qdxB","button-tertiary":"assets_groups_button-tertiary_1f4Jy","button-tag":"assets_groups_button-tag_yIgd9","button-icon":"assets_groups_button-icon_MSptS","button-icon-small":"assets_groups_button-icon-small_73Ir0","asset-element":"assets_groups_asset-element_RgKXH","group-title":"assets_groups_group-title_cV4AQ","pre-path":"assets_groups_pre-path_1rE71","path":"assets_groups_path_m0esc"}
|
|
@ -0,0 +1,19 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.group-title {
|
||||
padding-left: $s-16;
|
||||
.pre-path {
|
||||
text-transform: initial;
|
||||
color: var(--title-foreground-color);
|
||||
}
|
||||
.path {
|
||||
text-transform: initial;
|
||||
color: var(--title-foreground-color-hover);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,553 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.workspace.sidebar.assets.typographies
|
||||
(:require-macros [app.main.style :refer [css]])
|
||||
(:require
|
||||
[app.common.data :as d]
|
||||
[app.common.data.macros :as dm]
|
||||
[app.common.pages.helpers :as cph]
|
||||
[app.main.data.modal :as modal]
|
||||
[app.main.data.workspace.libraries :as dwl]
|
||||
[app.main.data.workspace.texts :as dwt]
|
||||
[app.main.data.workspace.undo :as dwu]
|
||||
[app.main.refs :as refs]
|
||||
[app.main.store :as st]
|
||||
[app.main.ui.context :as ctx]
|
||||
[app.main.ui.icons :as i]
|
||||
[app.main.ui.workspace.sidebar.assets.common :as cmm]
|
||||
[app.main.ui.workspace.sidebar.assets.groups :as grp]
|
||||
[app.main.ui.workspace.sidebar.options.menus.typography :refer [typography-entry]]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.i18n :as i18n :refer [tr]]
|
||||
[cuerdas.core :as str]
|
||||
[okulary.core :as l]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def lens:typography-section-state
|
||||
(l/derived (fn [gstate]
|
||||
{:rename-typography (:rename-typography gstate)
|
||||
:edit-typography (:edit-typography gstate)})
|
||||
refs/workspace-global
|
||||
=))
|
||||
|
||||
(mf/defc typography-item
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [typography file-id local? handle-change selected apply-typography editing-id renaming-id on-asset-click
|
||||
on-context-menu selected-full selected-paths move-typography rename?]}]
|
||||
(let [item-ref (mf/use-ref)
|
||||
typography-id (:id typography)
|
||||
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
editing? (= editing-id (:id typography))
|
||||
renaming? (= renaming-id (:id typography))
|
||||
|
||||
open* (mf/use-state editing?)
|
||||
open? (deref open*)
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps typography dragging* selected selected-full selected-paths move-typography)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset event typography dragging* selected selected-full
|
||||
selected-paths move-typography)))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps typography dragging* selected selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset event typography dragging* selected selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-typography-drag-start
|
||||
(mf/use-fn
|
||||
(mf/deps typography file-id selected item-ref read-only?)
|
||||
(fn [event]
|
||||
(if read-only?
|
||||
(dom/prevent-default event)
|
||||
(cmm/on-asset-drag-start event file-id typography selected item-ref :typographies identity))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps on-context-menu typography-id)
|
||||
(partial on-context-menu typography-id))
|
||||
|
||||
handle-change
|
||||
(mf/use-fn
|
||||
(mf/deps typography)
|
||||
(partial handle-change typography))
|
||||
|
||||
apply-typography
|
||||
(mf/use-fn
|
||||
(mf/deps typography)
|
||||
(partial apply-typography typography))
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn
|
||||
(mf/deps typography apply-typography on-asset-click)
|
||||
(partial on-asset-click typography-id apply-typography))]
|
||||
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :typography-item) true)
|
||||
:ref item-ref
|
||||
:draggable (and (not read-only?) (not open?))
|
||||
:on-drag-start on-typography-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& typography-entry
|
||||
{:typography typography
|
||||
:local? local?
|
||||
:on-context-menu on-context-menu
|
||||
:on-change handle-change
|
||||
:selected? (contains? selected typography-id)
|
||||
:on-click on-asset-click
|
||||
:editing? editing?
|
||||
:renaming? renaming?
|
||||
:focus-name? rename?
|
||||
:external-open* open*
|
||||
:file-id file-id}]
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (dom/classnames (css :dragging) true)}])]
|
||||
|
||||
[:div.typography-container {:ref item-ref
|
||||
:draggable (and (not read-only?) (not open?))
|
||||
:on-drag-start on-typography-drag-start
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& typography-entry
|
||||
{:typography typography
|
||||
:local? local?
|
||||
:on-context-menu on-context-menu
|
||||
:on-change handle-change
|
||||
:selected? (contains? selected typography-id)
|
||||
:on-click on-asset-click
|
||||
:editing? editing?
|
||||
:focus-name? rename?
|
||||
:external-open* open*
|
||||
:file-id file-id}]
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.dragging])])))
|
||||
|
||||
(mf/defc typographies-group
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file-id prefix groups open-groups file local? selected local-data
|
||||
editing-id renaming-id on-asset-click handle-change apply-typography on-rename-group
|
||||
on-ungroup on-context-menu selected-full]}]
|
||||
(let [group-open? (get open-groups prefix true)
|
||||
dragging* (mf/use-state false)
|
||||
dragging? (deref dragging*)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
selected-paths (mf/with-memo [selected-full]
|
||||
(into #{}
|
||||
(comp (map :path) (d/nilv ""))
|
||||
selected-full))
|
||||
move-typography
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(partial dwl/rename-typography file-id))
|
||||
|
||||
on-drag-enter
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths)
|
||||
(fn [event]
|
||||
(cmm/on-drag-enter-asset-group event dragging* prefix selected-paths)))
|
||||
|
||||
on-drag-leave
|
||||
(mf/use-fn
|
||||
(mf/deps dragging*)
|
||||
(fn [event]
|
||||
(cmm/on-drag-leave-asset event dragging*)))
|
||||
|
||||
on-drop
|
||||
(mf/use-fn
|
||||
(mf/deps dragging* prefix selected-paths selected-full move-typography)
|
||||
(fn [event]
|
||||
(cmm/on-drop-asset-group event dragging* prefix selected-paths selected-full move-typography)))]
|
||||
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :typographies-group) true)
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title {:file-id file-id
|
||||
:section :typographies
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [typographies (get groups "" [])]
|
||||
[:div {:class (dom/classnames (css :assets-list) true)
|
||||
:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div {:class (css :grid-placeholder)} "\u00A0"])
|
||||
|
||||
(when (and
|
||||
(empty? typographies)
|
||||
(some? groups))
|
||||
[:div {:class (css :drop-space)}])
|
||||
(for [{:keys [id] :as typography} typographies]
|
||||
[:& typography-item {:typography typography
|
||||
:key (dm/str "typography-" id)
|
||||
:file-id file-id
|
||||
:local? local?
|
||||
:handle-change handle-change
|
||||
:selected selected
|
||||
:apply-typography apply-typography
|
||||
:editing-id editing-id
|
||||
:renaming-id renaming-id
|
||||
:rename? (= (:rename-typography local-data) id)
|
||||
:on-asset-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths
|
||||
:move-typography move-typography}])])
|
||||
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& typographies-group {:file-id file-id
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:key (dm/str "group-" path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:file file
|
||||
:local? local?
|
||||
:selected selected
|
||||
:editing-id editing-id
|
||||
:renaming-id renaming-id
|
||||
:local-data local-data
|
||||
:on-asset-click on-asset-click
|
||||
:handle-change handle-change
|
||||
:apply-typography apply-typography
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]))])]
|
||||
[:div {:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
[:& grp/asset-group-title {:file-id file-id
|
||||
:section :typographies
|
||||
:path prefix
|
||||
:group-open? group-open?
|
||||
:on-rename on-rename-group
|
||||
:on-ungroup on-ungroup}]
|
||||
(when group-open?
|
||||
[:*
|
||||
(let [typographies (get groups "" [])]
|
||||
[:div.asset-list {:on-drag-enter on-drag-enter
|
||||
:on-drag-leave on-drag-leave
|
||||
:on-drag-over dom/prevent-default
|
||||
:on-drop on-drop}
|
||||
|
||||
(when ^boolean dragging?
|
||||
[:div.grid-placeholder "\u00A0"])
|
||||
|
||||
(when (and
|
||||
(empty? typographies)
|
||||
(some? groups))
|
||||
[:div.drop-space])
|
||||
(for [{:keys [id] :as typography} typographies]
|
||||
[:& typography-item {:typography typography
|
||||
:key (dm/str "typography-" id)
|
||||
:file-id file-id
|
||||
:local? local?
|
||||
:handle-change handle-change
|
||||
:selected selected
|
||||
:apply-typography apply-typography
|
||||
:editing-id editing-id
|
||||
:rename? (= (:rename-typography local-data) id)
|
||||
:on-asset-click on-asset-click
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full
|
||||
:selected-paths selected-paths
|
||||
:move-typography move-typography}])])
|
||||
|
||||
(for [[path-item content] groups]
|
||||
(when-not (empty? path-item)
|
||||
[:& typographies-group {:file-id file-id
|
||||
:prefix (cph/merge-path-item prefix path-item)
|
||||
:key (dm/str "group-" path-item)
|
||||
:groups content
|
||||
:open-groups open-groups
|
||||
:file file
|
||||
:local? local?
|
||||
:selected selected
|
||||
:editing-id editing-id
|
||||
:local-data local-data
|
||||
:on-asset-click on-asset-click
|
||||
:handle-change handle-change
|
||||
:apply-typography apply-typography
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]))])])))
|
||||
|
||||
(mf/defc typographies-section
|
||||
{::mf/wrap-props false}
|
||||
[{:keys [file file-id local? typographies open? open-status-ref selected reverse-sort?
|
||||
on-asset-click on-assets-delete on-clear-selection]}]
|
||||
(let [state (mf/use-state {:detail-open? false :id nil})
|
||||
local-data (mf/deref lens:typography-section-state)
|
||||
|
||||
read-only? (mf/use-ctx ctx/workspace-read-only?)
|
||||
new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
menu-state (mf/use-state cmm/initial-context-menu-state)
|
||||
typographies (mf/with-memo [typographies]
|
||||
(mapv dwl/extract-path-if-missing typographies))
|
||||
|
||||
groups (mf/with-memo [typographies reverse-sort?]
|
||||
(grp/group-assets typographies reverse-sort?))
|
||||
|
||||
selected (:typographies selected)
|
||||
selected-full (mf/with-memo [selected typographies]
|
||||
(into #{} (filter #(contains? selected (:id %))) typographies))
|
||||
|
||||
multi-typographies? (> (count selected) 1)
|
||||
multi-assets? (or (seq (:components selected))
|
||||
(seq (:graphics selected))
|
||||
(seq (:colors selected)))
|
||||
|
||||
open-groups-ref (mf/with-memo [open-status-ref]
|
||||
(-> (l/in [:groups :typographies])
|
||||
(l/derived open-status-ref)))
|
||||
|
||||
open-groups (mf/deref open-groups-ref)
|
||||
|
||||
add-typography
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [_]
|
||||
(st/emit! (dwt/add-typography file-id))))
|
||||
|
||||
handle-change
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [typography changes]
|
||||
(st/emit! (dwl/update-typography (merge typography changes) file-id))))
|
||||
|
||||
apply-typography
|
||||
(mf/use-fn
|
||||
(mf/deps file-id)
|
||||
(fn [typography _event]
|
||||
(st/emit! (dwt/apply-typography typography file-id))))
|
||||
|
||||
create-group
|
||||
(mf/use-fn
|
||||
(mf/deps typographies selected on-clear-selection file-id (:id @state))
|
||||
(fn [group-name]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> typographies
|
||||
(filter #(if multi-typographies?
|
||||
(contains? selected (:id %))
|
||||
(= (:id @state) (:id %))))
|
||||
(map #(dwl/update-typography
|
||||
(assoc % :name
|
||||
(cmm/add-group % group-name))
|
||||
file-id))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps typographies)
|
||||
(fn [path last-path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(run! st/emit!
|
||||
(->> typographies
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/update-typography
|
||||
(assoc % :name
|
||||
(cmm/rename-group % path last-path))
|
||||
file-id))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-group
|
||||
(mf/use-fn
|
||||
(mf/deps typographies selected create-group)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:accept create-group})))
|
||||
|
||||
on-rename-group
|
||||
(mf/use-fn
|
||||
(mf/deps typographies)
|
||||
(fn [event path last-path]
|
||||
(dom/stop-propagation event)
|
||||
(modal/show! :name-group-dialog {:path path
|
||||
:last-path last-path
|
||||
:accept rename-group})))
|
||||
on-ungroup
|
||||
(mf/use-fn
|
||||
(mf/deps typographies)
|
||||
(fn [path]
|
||||
(on-clear-selection)
|
||||
(let [undo-id (js/Symbol)]
|
||||
(st/emit! (dwu/start-undo-transaction undo-id))
|
||||
(apply st/emit!
|
||||
(->> typographies
|
||||
(filter #(str/starts-with? (:path %) path))
|
||||
(map #(dwl/rename-typography
|
||||
file-id
|
||||
(:id %)
|
||||
(cmm/ungroup % path)))))
|
||||
(st/emit! (dwu/commit-undo-transaction undo-id)))))
|
||||
|
||||
on-context-menu
|
||||
(mf/use-fn
|
||||
(mf/deps selected on-clear-selection read-only?)
|
||||
(fn [id event]
|
||||
(dom/prevent-default event)
|
||||
(let [pos (dom/get-client-position event)]
|
||||
(when (and local? (not read-only?))
|
||||
(when-not (contains? selected id)
|
||||
(on-clear-selection))
|
||||
(swap! state assoc :id id)
|
||||
(swap! menu-state cmm/open-context-menu pos)))))
|
||||
|
||||
on-close-menu
|
||||
(mf/use-fn
|
||||
(fn []
|
||||
(swap! menu-state cmm/close-context-menu)))
|
||||
|
||||
handle-rename-typography-clicked
|
||||
(fn []
|
||||
(st/emit! #(assoc-in % [:workspace-global :rename-typography] (:id @state))))
|
||||
|
||||
handle-edit-typography-clicked
|
||||
(fn []
|
||||
(st/emit! #(assoc-in % [:workspace-global :edit-typography] (:id @state))))
|
||||
|
||||
handle-delete-typography
|
||||
(mf/use-fn
|
||||
(mf/deps @state multi-typographies? multi-assets?)
|
||||
(fn []
|
||||
(let [undo-id (js/Symbol)]
|
||||
(if (or multi-typographies? multi-assets?)
|
||||
(on-assets-delete)
|
||||
(st/emit! (dwu/start-undo-transaction undo-id)
|
||||
(dwl/delete-typography (:id @state))
|
||||
(dwl/sync-file file-id file-id :typographies (:id @state))
|
||||
(dwu/commit-undo-transaction undo-id))))))
|
||||
|
||||
editing-id (if new-css-system
|
||||
(:edit-typography local-data)
|
||||
(or (:rename-typography local-data)
|
||||
(:edit-typography local-data)))
|
||||
|
||||
renaming-id (:rename-typography local-data)
|
||||
|
||||
on-asset-click
|
||||
(mf/use-fn
|
||||
(mf/deps groups on-asset-click)
|
||||
(partial on-asset-click groups))]
|
||||
|
||||
(mf/use-effect
|
||||
(mf/deps local-data new-css-system)
|
||||
(fn []
|
||||
(when (and (not new-css-system)(:rename-typography local-data))
|
||||
(st/emit! #(update % :workspace-global dissoc :rename-typography)))
|
||||
(when (:edit-typography local-data)
|
||||
(st/emit! #(update % :workspace-global dissoc :edit-typography)))))
|
||||
|
||||
[:& cmm/asset-section {:file-id file-id
|
||||
:title (tr "workspace.assets.typography")
|
||||
:section :typographies
|
||||
:assets-count (count typographies)
|
||||
:open? open?}
|
||||
(if ^boolean new-css-system
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when-not read-only?
|
||||
[:button {:class (dom/classnames (css :assets-btn) true)
|
||||
:on-click add-typography}
|
||||
i/add-refactor])])
|
||||
|
||||
(when local?
|
||||
[:& cmm/asset-section-block {:role :title-button}
|
||||
(when-not read-only?
|
||||
[:div.assets-button {:on-click add-typography}
|
||||
i/plus])]))
|
||||
|
||||
[:& cmm/asset-section-block {:role :content}
|
||||
[:& typographies-group {:file-id file-id
|
||||
:prefix ""
|
||||
:groups groups
|
||||
:open-groups open-groups
|
||||
:state state
|
||||
:file file
|
||||
:local? local?
|
||||
:selected selected
|
||||
:editing-id editing-id
|
||||
:renaming-id renaming-id
|
||||
:local-data local-data
|
||||
:on-asset-click on-asset-click
|
||||
:handle-change handle-change
|
||||
:apply-typography apply-typography
|
||||
:on-rename-group on-rename-group
|
||||
:on-ungroup on-ungroup
|
||||
:on-context-menu on-context-menu
|
||||
:selected-full selected-full}]
|
||||
|
||||
(when local?
|
||||
[:& cmm/assets-context-menu
|
||||
{:on-close on-close-menu
|
||||
:state @menu-state
|
||||
:options (if new-css-system
|
||||
[(when-not (or multi-typographies? multi-assets?)
|
||||
{:option-name (tr "workspace.assets.rename")
|
||||
:id "assets-rename-typography"
|
||||
:option-handler handle-rename-typography-clicked})
|
||||
|
||||
(when-not (or multi-typographies? multi-assets?)
|
||||
{:option-name (tr "workspace.assets.edit")
|
||||
:id "assets-edit-typography"
|
||||
:option-handler handle-edit-typography-clicked})
|
||||
|
||||
{:option-name (tr "workspace.assets.delete")
|
||||
:id "assets-delete-typography"
|
||||
:option-handler handle-delete-typography}
|
||||
|
||||
(when-not multi-assets?
|
||||
{:option-name (tr "workspace.assets.group")
|
||||
:id "assets-group-typography"
|
||||
:option-handler on-group})]
|
||||
|
||||
|
||||
[(when-not (or multi-typographies? multi-assets?)
|
||||
[(tr "workspace.assets.rename") handle-rename-typography-clicked])
|
||||
(when-not (or multi-typographies? multi-assets?)
|
||||
[(tr "workspace.assets.edit") handle-edit-typography-clicked])
|
||||
[(tr "workspace.assets.delete") handle-delete-typography]
|
||||
(when-not multi-assets?
|
||||
[(tr "workspace.assets.group") on-group])])}])]]))
|
|
@ -0,0 +1 @@
|
|||
{"button-primary":"assets_typographies_button-primary_njVYq","button-secondary":"assets_typographies_button-secondary_Wzmmw","button-tertiary":"assets_typographies_button-tertiary_k3V5a","assets-btn":"assets_typographies_assets-btn_wCF-m","button-tag":"assets_typographies_button-tag_grTbB","button-icon":"assets_typographies_button-icon_7peoi","button-icon-small":"assets_typographies_button-icon-small_oHD9w","asset-element":"assets_typographies_asset-element_hvNzY","typographies-group":"assets_typographies_typographies-group_iCR4V","assets-list":"assets_typographies_assets-list_wS3At","drop-space":"assets_typographies_drop-space_kGrjB","grid-placeholder":"assets_typographies_grid-placeholder_FvcCI","typography-item":"assets_typographies_typography-item_qkADe","dragging":"assets_typographies_dragging_Ns4o7"}
|
|
@ -0,0 +1,51 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@import "refactor/common-refactor.scss";
|
||||
|
||||
.assets-btn {
|
||||
@extend .button-tertiary;
|
||||
height: $s-32;
|
||||
width: calc($s-24 + $s-4);
|
||||
padding: 0;
|
||||
border-radius: $br-8;
|
||||
svg {
|
||||
@extend .button-icon;
|
||||
}
|
||||
}
|
||||
.typographies-group {
|
||||
.assets-list {
|
||||
padding: 0 0 0 $s-12;
|
||||
.drop-space {
|
||||
height: $s-12;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
}
|
||||
.grid-placeholder {
|
||||
height: $s-2;
|
||||
width: 100%;
|
||||
background-color: var(--color-accent-primary);
|
||||
}
|
||||
.typography-item {
|
||||
position: relative;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $s-4;
|
||||
border-radius: $br-8;
|
||||
background-color: var(--assets-item-background-color);
|
||||
}
|
||||
.dragging {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
border: $s-2 solid var(--assets-item-border-color-drag);
|
||||
border-radius: $s-8;
|
||||
background-color: var(--assets-item-background-color-drag);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,9 +18,9 @@
|
|||
(mf/defc collapsed-button
|
||||
{::mf/wrap-props false}
|
||||
[]
|
||||
(let [new-css? (mf/use-ctx ctx/new-css-system)
|
||||
(let [new-css-system (mf/use-ctx ctx/new-css-system)
|
||||
on-click (mf/use-fn #(st/emit! (dw/toggle-layout-flag :collapse-left-sidebar)))]
|
||||
(if ^boolean new-css?
|
||||
(if ^boolean new-css-system
|
||||
[:div {:class (dom/classnames (css :collapsed-sidebar) true)}
|
||||
[:div {:class (dom/classnames (css :collapsed-title) true)}
|
||||
[:button {:class (dom/classnames (css :collapsed-button) true)
|
||||
|
|
|
@ -1 +1 @@
|
|||
{"button-primary":"sidebar_collapsable_button_button-primary_qaRce","button-secondary":"sidebar_collapsable_button_button-secondary_OqDpe","button-icon":"sidebar_collapsable_button_button-icon_P4-xy","button-icon-small":"sidebar_collapsable_button_button-icon-small_lQUE3","collapsed-sidebar":"sidebar_collapsable_button_collapsed-sidebar_uQnGJ","collapsed-title":"sidebar_collapsable_button_collapsed-title_Jb62g","collapsed-button":"sidebar_collapsable_button_collapsed-button_LT5ME"}
|
||||
{"button-primary":"sidebar_collapsable_button_button-primary_qaRce","button-secondary":"sidebar_collapsable_button_button-secondary_OqDpe","button-tertiary":"sidebar_collapsable_button_button-tertiary_NuJrA","button-tag":"sidebar_collapsable_button_button-tag_unQKq","button-icon":"sidebar_collapsable_button_button-icon_P4-xy","button-icon-small":"sidebar_collapsable_button_button-icon-small_lQUE3","asset-element":"sidebar_collapsable_button_asset-element_BboJ7","collapsed-sidebar":"sidebar_collapsable_button_collapsed-sidebar_uQnGJ","collapsed-title":"sidebar_collapsable_button_collapsed-title_Jb62g","collapsed-button":"sidebar_collapsable_button_collapsed-button_LT5ME"}
|
|
@ -1 +1 @@
|
|||
{"button-primary":"sidebar_layer_item_button-primary_74ST4","button-secondary":"sidebar_layer_item_button-secondary_e4u9V","button-icon":"sidebar_layer_item_button-icon_-D7KH","button-icon-small":"sidebar_layer_item_button-icon-small_1RfDl","layer-row":"sidebar_layer_item_layer-row_KibLX","element-list-body":"sidebar_layer_item_element-list-body_832JO","element-actions":"sidebar_layer_item_element-actions_ACGJI","toggle-element":"sidebar_layer_item_toggle-element_4bhRW","block-element":"sidebar_layer_item_block-element_RhKz-","button-content":"sidebar_layer_item_button-content_bPwop","icon-shape":"sidebar_layer_item_icon-shape_g9Wxn","toggle-content":"sidebar_layer_item_toggle-content_MKhsv","filtered":"sidebar_layer_item_filtered_V5CHf","inverse":"sidebar_layer_item_inverse_zzZ54","absolute":"sidebar_layer_item_absolute_mYIKg","selected":"sidebar_layer_item_selected_O7P-j","element-children":"sidebar_layer_item_element-children_3iA4Q","parent-selected":"sidebar_layer_item_parent-selected_uIIyQ","hidden":"sidebar_layer_item_hidden_JRbJO","type-comp":"sidebar_layer_item_type-comp_FBSRt","tab-indentation":"sidebar_layer_item_tab-indentation_e-2dQ"}
|
||||
{"button-primary":"sidebar_layer_item_button-primary_74ST4","button-secondary":"sidebar_layer_item_button-secondary_e4u9V","button-tertiary":"sidebar_layer_item_button-tertiary_Mo--6","button-tag":"sidebar_layer_item_button-tag_lFKoD","button-icon":"sidebar_layer_item_button-icon_-D7KH","button-icon-small":"sidebar_layer_item_button-icon-small_1RfDl","layer-row":"sidebar_layer_item_layer-row_KibLX","element-list-body":"sidebar_layer_item_element-list-body_832JO","element-actions":"sidebar_layer_item_element-actions_ACGJI","toggle-element":"sidebar_layer_item_toggle-element_4bhRW","block-element":"sidebar_layer_item_block-element_RhKz-","button-content":"sidebar_layer_item_button-content_bPwop","icon-shape":"sidebar_layer_item_icon-shape_g9Wxn","toggle-content":"sidebar_layer_item_toggle-content_MKhsv","asset-element":"sidebar_layer_item_asset-element_AXTD0","filtered":"sidebar_layer_item_filtered_V5CHf","inverse":"sidebar_layer_item_inverse_zzZ54","absolute":"sidebar_layer_item_absolute_mYIKg","selected":"sidebar_layer_item_selected_O7P-j","element-children":"sidebar_layer_item_element-children_3iA4Q","parent-selected":"sidebar_layer_item_parent-selected_uIIyQ","hidden":"sidebar_layer_item_hidden_JRbJO","type-comp":"sidebar_layer_item_type-comp_FBSRt","tab-indentation":"sidebar_layer_item_tab-indentation_e-2dQ"}
|
|
@ -1 +1 @@
|
|||
{"button-primary":"sidebar_layer_name_button-primary_V-6Cp","button-secondary":"sidebar_layer_name_button-secondary_Q14Qj","button-icon":"sidebar_layer_name_button-icon_UQXjw","button-icon-small":"sidebar_layer_name_button-icon-small_At5P8","element-name":"sidebar_layer_name_element-name_hZ-lA","selected":"sidebar_layer_name_selected_MKxdm","type-comp":"sidebar_layer_name_type-comp_TNGM-","hidden":"sidebar_layer_name_hidden_e-K3G","element-name-input":"sidebar_layer_name_element-name-input_Wpnkf"}
|
||||
{"button-primary":"sidebar_layer_name_button-primary_V-6Cp","button-secondary":"sidebar_layer_name_button-secondary_Q14Qj","button-tertiary":"sidebar_layer_name_button-tertiary_dA-v0","button-tag":"sidebar_layer_name_button-tag_fr2K0","button-icon":"sidebar_layer_name_button-icon_UQXjw","button-icon-small":"sidebar_layer_name_button-icon-small_At5P8","asset-element":"sidebar_layer_name_asset-element_WVekz","element-name":"sidebar_layer_name_element-name_hZ-lA","selected":"sidebar_layer_name_selected_MKxdm","type-comp":"sidebar_layer_name_type-comp_TNGM-","hidden":"sidebar_layer_name_hidden_e-K3G","element-name-input":"sidebar_layer_name_element-name-input_Wpnkf"}
|
|
@ -28,6 +28,7 @@
|
|||
.element-name-input {
|
||||
@include textEllipsis;
|
||||
@include titleTipography;
|
||||
@include removeInputStyle;
|
||||
flex-grow: 1;
|
||||
height: $s-28;
|
||||
max-width: calc(var(--parent-size) - (var(--depth) * var(--layer-indentation-size)));
|
||||
|
@ -35,7 +36,5 @@
|
|||
padding-left: $s-6;
|
||||
border-radius: $br-8;
|
||||
border: 1px solid var(--input-border-color-focus);
|
||||
outline: none;
|
||||
background-color: transparent;
|
||||
color: var(--layer-row-foreground-color);
|
||||
}
|
||||
|
|