|
@@ -0,0 +1,207 @@
|
|
|
+import { css, cx } from "@linaria/core";
|
|
|
+import Pickr from "@simonwep/pickr";
|
|
|
+import {
|
|
|
+ computed,
|
|
|
+ defineComponent,
|
|
|
+ onMounted,
|
|
|
+ onUnmounted,
|
|
|
+ reactive,
|
|
|
+ watch,
|
|
|
+} from "vue";
|
|
|
+
|
|
|
+import "@simonwep/pickr/dist/themes/nano.min.css"; // 'nano' theme
|
|
|
+import { bool, string } from "vue-types";
|
|
|
+
|
|
|
+const defaultColor = [
|
|
|
+ "rgba(255, 255, 255, 0)",
|
|
|
+ // "rgba(233, 30, 99, 1)",
|
|
|
+ // "rgba(156, 39, 176, 1)",
|
|
|
+ // "rgba(103, 58, 183, 1)",
|
|
|
+ // "rgba(63, 81, 181, 1)",
|
|
|
+ "rgba(33, 150, 243, 1)",
|
|
|
+ "rgba(3, 169, 244, 1)",
|
|
|
+ "rgba(0, 188, 212, 1)",
|
|
|
+ "rgba(0, 150, 136, 1)",
|
|
|
+ "rgba(76, 175, 80, 1)",
|
|
|
+ "rgba(139, 195, 74, 1)",
|
|
|
+ "rgba(205, 220, 57, 1)",
|
|
|
+ "rgba(255, 235, 59, 1)",
|
|
|
+ "rgba(255, 193, 7, 1)",
|
|
|
+];
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ props: {
|
|
|
+ value: string().isRequired,
|
|
|
+ disabled: bool(),
|
|
|
+ },
|
|
|
+ emits: ["change"],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ let pickr: any = null;
|
|
|
+
|
|
|
+ // @ts-ignore
|
|
|
+ const state = reactive({
|
|
|
+ index: 0,
|
|
|
+ colorList: [props.value, ...defaultColor],
|
|
|
+ color: computed(() => state.colorList[state.index]),
|
|
|
+ });
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ initPicker();
|
|
|
+ });
|
|
|
+
|
|
|
+ onUnmounted(() => {
|
|
|
+ pickr.destroyAndRemove();
|
|
|
+ });
|
|
|
+
|
|
|
+ function initPicker() {
|
|
|
+ pickr = Pickr.create({
|
|
|
+ el: ".color-picker",
|
|
|
+ theme: "nano",
|
|
|
+ default: props.value,
|
|
|
+ i18n: {
|
|
|
+ "btn:save": "确定",
|
|
|
+ },
|
|
|
+ swatches: defaultColor,
|
|
|
+ components: {
|
|
|
+ preview: true,
|
|
|
+ opacity: false,
|
|
|
+ hue: true,
|
|
|
+ interaction: {
|
|
|
+ hex: false,
|
|
|
+ rgba: false,
|
|
|
+ input: true,
|
|
|
+ save: true,
|
|
|
+ },
|
|
|
+ },
|
|
|
+ });
|
|
|
+
|
|
|
+ // pickr.on("init", () => {
|
|
|
+ // console.log('Event: "init"', instance);
|
|
|
+ // });
|
|
|
+
|
|
|
+ pickr.on("change", (color: any) => {
|
|
|
+ const hexa = color.toHEXA().toString();
|
|
|
+ state.colorList[state.index] = hexa;
|
|
|
+ emit("change", hexa);
|
|
|
+ });
|
|
|
+
|
|
|
+ pickr.on("save", (color: any) => {
|
|
|
+ pickr.hide();
|
|
|
+ const hexa = color.toHEXA().toString();
|
|
|
+ state.colorList[state.index] = hexa;
|
|
|
+ emit("change", hexa);
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ const show = () => {
|
|
|
+ pickr.show();
|
|
|
+ };
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => props.value,
|
|
|
+ () => {
|
|
|
+ if (props.value) {
|
|
|
+ state.colorList[state.index] = props.value;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ return () => {
|
|
|
+ const { disabled = false } = props;
|
|
|
+
|
|
|
+ return (
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ ColorPiackerView,
|
|
|
+ "overflow-hidden flex-1",
|
|
|
+ { "picker-disabled": disabled },
|
|
|
+ ]}
|
|
|
+ >
|
|
|
+ <div class="color_view flex items-center">
|
|
|
+ <div
|
|
|
+ class="color_icon color_item w-30px h-30px mx-3px mb-5px rounded-2px cursor-pointer"
|
|
|
+ onClick={() => (disabled ? null : show())}
|
|
|
+ ></div>
|
|
|
+
|
|
|
+ {state.colorList.map((color: string, index: number) => (
|
|
|
+ <div
|
|
|
+ class={cx(
|
|
|
+ index == state.index && "item_active",
|
|
|
+ color == defaultColor[0] && "item_empty",
|
|
|
+ "color_item w-30px h-30px mx-3px mb-5px rounded-2px cursor-pointer"
|
|
|
+ )}
|
|
|
+ style={{ backgroundColor: color }}
|
|
|
+ key={index}
|
|
|
+ onClick={() => {
|
|
|
+ state.index = index;
|
|
|
+ emit("change", color);
|
|
|
+ }}
|
|
|
+ ></div>
|
|
|
+ ))}
|
|
|
+ </div>
|
|
|
+ <div class="color-picker"></div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ };
|
|
|
+ },
|
|
|
+});
|
|
|
+
|
|
|
+const ColorPiackerView = css`
|
|
|
+ position: relative;
|
|
|
+ &.picker-disabled {
|
|
|
+ cursor: not-allowed;
|
|
|
+ }
|
|
|
+ .pickr {
|
|
|
+ font-size: 0;
|
|
|
+ line-height: 0;
|
|
|
+ }
|
|
|
+ .pickr .pcr-button {
|
|
|
+ height: 0;
|
|
|
+ padding: 0;
|
|
|
+ }
|
|
|
+ .color_view {
|
|
|
+ flex-wrap: wrap;
|
|
|
+ .color_item {
|
|
|
+ border-radius: 3px;
|
|
|
+ position: relative;
|
|
|
+ &::after {
|
|
|
+ border-radius: 2px;
|
|
|
+ content: "";
|
|
|
+ position: absolute;
|
|
|
+ right: 0;
|
|
|
+ left: 0;
|
|
|
+ top: 0;
|
|
|
+ bottom: 0;
|
|
|
+ transition: box-shadow 0.2s ease-in-out;
|
|
|
+ }
|
|
|
+ &.item_active {
|
|
|
+ box-shadow: 0 0 0 1px @inf-border-color,
|
|
|
+ inset 0 0 0 1px @inf-border-color, inset 0 0 0 3px #fff;
|
|
|
+ }
|
|
|
+ &.item_empty {
|
|
|
+ background: url("@/assets/imgs/bgBlank.svg") repeat;
|
|
|
+ background-color: #fff !important;
|
|
|
+ }
|
|
|
+ &:hover {
|
|
|
+ box-shadow: 0 0 0 1px @inf-border-color,
|
|
|
+ inset 0 0 0 1px @inf-border-color, inset 0 0 0 3px #fff;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .color_icon {
|
|
|
+ background-image: url("@/assets/imgs/bgColor.png");
|
|
|
+ background-repeat: no-repeat;
|
|
|
+ background-size: cover;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .color_input,
|
|
|
+ .pickr {
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ bottom: 0;
|
|
|
+ width: 100%;
|
|
|
+ height: 0;
|
|
|
+ padding: 0;
|
|
|
+ border: none;
|
|
|
+ visibility: hidden;
|
|
|
+ }
|
|
|
+`;
|