style(components): canonical code

This commit is contained in:
xiaoxian521
2021-07-05 20:49:32 +08:00
parent f96a2e4d00
commit 0adc256d53
71 changed files with 400 additions and 1078 deletions

View File

@@ -0,0 +1,44 @@
.clearfix:after {
visibility: hidden;
display: block;
font-size: 0;
content: " ";
clear: both;
height: 0;
}
.vue-splitter-container {
height: 100%;
position: relative;
}
.vue-splitter-container-mask {
z-index: 9999;
width: 100%;
height: 100%;
position: absolute;
top: 0;
left: 0;
}
.splitter-pane.vertical.splitter-paneL {
position: absolute;
left: 0px;
height: 100%;
padding-right: 3px;
}
.splitter-pane.vertical.splitter-paneR {
position: absolute;
right: 0px;
height: 100%;
padding-left: 3px;
}
.splitter-pane.horizontal.splitter-paneL {
position: absolute;
top: 0px;
width: 100%;
}
.splitter-pane.horizontal.splitter-paneR {
position: absolute;
bottom: 0px;
width: 100%;
padding-top: 3px;
}

View File

@@ -0,0 +1,139 @@
import { defineComponent, ref, unref, computed, PropType } from "vue";
import resizer from "./resizer";
import "./index.css";
export interface ContextProps {
minPercent: number;
defaultPercent: number;
split: string;
}
export default defineComponent({
name: "splitPane",
components: { resizer },
props: {
splitSet: {
type: Object as PropType<ContextProps>,
require: true,
},
},
emits: ["resize"],
setup(props, ctx) {
let active = ref(false);
let hasMoved = ref(false);
let percent = ref(props.splitSet?.defaultPercent);
let type = props.splitSet?.split === "vertical" ? "width" : "height";
let resizeType = props.splitSet?.split === "vertical" ? "left" : "top";
let leftClass = ref([
"splitter-pane splitter-paneL",
props.splitSet?.split,
]);
let rightClass = ref([
"splitter-pane splitter-paneR",
props.splitSet?.split,
]);
const userSelect = computed(() => {
return active.value ? "none" : "";
});
const cursor = computed(() => {
return active.value
? props.splitSet?.split === "vertical"
? "col-resize"
: "row-resize"
: "";
});
const onClick = (): void => {
if (!hasMoved.value) {
percent.value = 50;
ctx.emit("resize", percent.value);
}
};
const onMouseDown = (): void => {
active.value = true;
hasMoved.value = false;
};
const onMouseUp = (): void => {
active.value = false;
};
const onMouseMove = (e: any): void => {
if (e.buttons === 0 || e.which === 0) {
active.value = false;
}
if (active.value) {
let offset = 0;
let target = e.currentTarget;
if (props.splitSet?.split === "vertical") {
while (target) {
offset += target.offsetLeft;
target = target.offsetParent;
}
} else {
while (target) {
offset += target.offsetTop;
target = target.offsetParent;
}
}
const currentPage =
props.splitSet?.split === "vertical" ? e.pageX : e.pageY;
const targetOffset =
props.splitSet?.split === "vertical"
? e.currentTarget.offsetWidth
: e.currentTarget.offsetHeight;
const percents =
Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100;
if (
percents > props.splitSet?.minPercent &&
percents < 100 - props.splitSet?.minPercent
) {
percent.value = percents;
}
ctx.emit("resize", percent.value);
hasMoved.value = true;
}
};
return () => (
<>
<div
class="vue-splitter-container clearfix"
style={(unref(cursor), unref(userSelect))}
onMouseup={() => onMouseUp()}
onMousemove={() => onMouseMove(event)}
>
<div
class={unref(leftClass)}
style={{ [unref(type)]: unref(percent) + "%" }}
>
{ctx.slots.paneL()}
</div>
<resizer
style={`${unref([resizeType])}:${unref(percent)}%`}
split={props.splitSet?.split}
onMousedown={() => onMouseDown()}
onClick={() => onClick()}
></resizer>
<div
class={unref(rightClass)}
style={{ [unref(type)]: 100 - unref(percent) + "%" }}
>
{ctx.slots.paneR()}
</div>
<div v-show={unref(active)} class="vue-splitter-container-mask"></div>
</div>
</>
);
},
});

View File

@@ -0,0 +1,28 @@
.splitter-pane-resizer {
-moz-box-sizing: border-box;
-webkit-box-sizing: border-box;
box-sizing: border-box;
background: #000;
position: absolute;
opacity: 0.2;
z-index: 1;
-moz-background-clip: padding;
-webkit-background-clip: padding;
background-clip: padding-box;
}
.splitter-pane-resizer.horizontal {
height: 11px;
margin: -5px 0;
border-top: 5px solid rgba(255, 255, 255, 0);
border-bottom: 5px solid rgba(255, 255, 255, 0);
cursor: row-resize;
width: 100%;
}
.splitter-pane-resizer.vertical {
width: 11px;
height: 100%;
margin-left: -5px;
border-left: 5px solid rgba(255, 255, 255, 0);
border-right: 5px solid rgba(255, 255, 255, 0);
cursor: col-resize;
}

View File

@@ -0,0 +1,23 @@
import { computed, unref, defineComponent } from "vue";
import "./resizer.css";
export default defineComponent({
name: "resizer",
props: {
split: {
type: String,
required: true,
},
className: {
type: String,
default: "",
},
},
setup(props) {
let classes = computed(() => {
return ["splitter-pane-resizer", props.split, props.className].join(" ");
});
return () => <div class={unref(classes)}></div>;
},
});