box-shadow阴影选择器-react

请添加图片描述

1.0代码 同步代码仓库 : https://gitee.com/honbingitee/ruyi-lowcode. src/component/BoxShadow/index.tsx

/*
 * @Author: hongbin
 * @Date: 2022-05-02 21:20:18
 * @LastEditors: hongbin
 * @LastEditTime: 2022-05-04 08:28:09
 * @Description:box-shadow pick
 */
import { FC, ReactElement, useEffect, useRef } from "react";
import styled, { css } from "styled-components";
import { IShadow } from "../ElementProvider/ElementList";
import ProgressBar from "../ProgressBar";

interface IProps {
  style?: React.CSSProperties;
  shadow: IShadow;
  setShadowItem: (key: keyof IShadow, val: number | boolean) => void;
  onCancel: () => void;
  onCompute: () => void;
}

const BoxShadowPick: FC<IProps> = ({ style = {}, shadow, setShadowItem, onCancel, onCompute }): ReactElement => {
  const wrapRef = useRef<HTMLDivElement>(null);
  const panelRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (wrapRef.current && panelRef.current) {
      const { offsetWidth } = wrapRef.current;
      panelRef.current.style["width"] = offsetWidth / 2 + "px";
      panelRef.current.style["height"] = offsetWidth / 2 + "px";
    }
  }, []);

  return (
    <Container style={{ ...style }} ref={wrapRef}>
      <RowFlex>
        <Button onClick={() => setShadowItem("inset", false)} selected={!shadow.inset}>
          外阴影
        </Button>
        <Button onClick={() => setShadowItem("inset", true)} selected={shadow.inset}>
          内阴影
        </Button>
      </RowFlex>
      <Panel ref={panelRef}>
        <Spot
          style={{
            transform: `translate(${shadow.x}px,${shadow.y}px)`,
          }}
          onMouseDown={(e) => {
            const { pageX: startX, pageY: startY } = e;
            const maxDistance = panelRef.current!.offsetWidth / 2;
            const { x, y } = shadow;
            const move = (e: MouseEvent) => {
              const disX = x + (e.pageX - startX);
              const disY = y + (e.pageY - startY);

              if (maxDistance >= Math.abs(disX)) setShadowItem("x", disX);
              if (maxDistance >= Math.abs(disY)) setShadowItem("y", disY);
            };

            const clear = () => {
              document.removeEventListener("mousemove", move);
              document.removeEventListener("mouseup", clear);
              document.removeEventListener("mouseleave", clear);
            };

            document.addEventListener("mousemove", move);
            document.addEventListener("mouseleave", clear);
            document.addEventListener("mouseup", clear);
          }}
        />
      </Panel>
      <RowFlex>
        <span>模糊</span>
        <ProgressBar
          value={shadow.blur / 10}
          onChange={(percent) => {
            setShadowItem("blur", percent * 10);
          }}
          style={{ width: "9vw" }}
        />
        <span>{shadow.blur.toFixed(1)}</span>
      </RowFlex>
      <RowFlex>
        <span>范围</span>
        <ProgressBar
          value={shadow.spread / 10}
          onChange={(percent) => {
            setShadowItem("spread", percent * 10);
          }}
          style={{ width: "9vw" }}
        />
        <span>{shadow.spread.toFixed(1)}</span>
      </RowFlex>
      <RowFlex>
        <Button onClick={onCancel} selected={false}>
          取消
        </Button>
        <Button onClick={onCompute} selected={true}>
          确定
        </Button>
      </RowFlex>
    </Container>
  );
};

export default BoxShadowPick;

const Spot = styled.div`
  position: absolute;
  width: 0.75vw;
  height: 0.75vw;
  border-radius: 1vw;
  background-color: var(--deep-color, #1340f4);
  cursor: pointer;
  z-index: 2;
`;

const Panel = styled.div`
  background-color: var(--tint-color, #f7f7f7);
  position: relative;
  overflow: hidden;
  display: flex;
  justify-content: center;
  align-items: center;
  margin-top: 0.5vh;

  ::before,
  ::after {
    content: "";
    border: 1px dotted var(--deep-color, #1340f4);
    border-left: none;
    border-top: none;
    position: absolute;
  }

  ::before {
    height: inherit;
  }
  ::after {
    width: inherit;
  }
`;

const Button = styled.button<{ selected: boolean }>`
  cursor: pointer;
  border: none;
  outline: none;
  border-radius: 0.3vh;
  width: 40%;
  height: 2.3vh;
  background-color: var(--tint-color, #eee);
  color: var(--deep-color, #999);
  letter-spacing: 1px;
  font-size: 0.8vw;
  transform: 0.3s linear;
  transition-property: background-color, color, font-weight;
  ${(props) =>
    props.selected &&
    css`
      background-color: var(--deep-color, #1340f4);
      color: var(--tint-color, #fffae5);
      font-weight: bold;
    `};
`;

const RowFlex = styled.div`
  display: flex;
  align-items: center;
  width: inherit;
  justify-content: space-evenly;
`;

const Container = styled.div`
  width: 15vw;
  height: 30vh;
  border-radius: 1vh;
  background: #fff;
  box-shadow: 1px 2px 3px 1px #ccc;
  z-index: 1;
  display: flex;
  justify-content: space-evenly;
  align-items: center;
  flex-direction: column;
  padding: 1vh 0;
`;

### 如何去除 Ant Design `a-select` 组件的 Focus 焦点样式 对于 Ant Design 的 `Select` 组件,可以通过自定义 CSS 来移除默认的焦点样式。由于 Ant Design 使用了特定的选择器来应用这些样式,因此需要通过更具体的 CSS 或者使用 `:global` 关键字来覆盖原有样式。 #### React 实现方法 在 React 中实现时,可以采用如下方式: ```css /* styles.css */ .selectBoxWrapper { :global { .ant-select-selector:focus, .ant-select-focused:not(.ant-select-disabled) .ant-select-selector, .ant-select-selection-search-input:focus{ border-color: initial; box-shadow: none !important; outline: none; } } } ``` ```jsx // MyComponent.jsx import React from 'react'; import './styles.css'; import { Select } from 'antd'; const MyComponent = () => ( <div className="selectBoxWrapper"> <Select className="selectBox" placeholder="请选择..." /> </div> ); export default MyComponent; ``` 上述代码片段展示了如何利用`:global`关键字确保能够正确地覆盖 Ant Design 提供的基础样式[^2]。 #### Vue 实现方法 针对 Vue 用户而言,如果希望达到相同效果,则可以在单文件组件内编写类似的 SCSS/SASS/CSS 并加上适当的作用域控制: ```scss <style scoped lang="scss"> @import "~@/assets/styles/mixins"; .custom-select-wrapper { ::v-deep .ant-select-selector:focus, ::v-deep .ant-select-focused:not(.ant-select-disabled) .ant-select-selector, ::v-deep .ant-select-selection-search-input:focus { border-color: unset !important; box-shadow: none !important; outline: none; } } </style> <template> <div class="custom-select-wrapper"> <a-select></a-select> </div> </template> ``` 这里采用了 `::v-deep` 指令让子组件中的样式也能受到影响,从而有效地去除了聚焦状态下的边框颜色变化以及阴影效果[^4]。 #### 注意事项 当调整第三方库提供的 UI 控件外观时,请务必测试不同浏览器环境下的表现一致性,并确认不会意外影响页面上的其他部分。另外,考虑到未来版本更新可能带来的兼容性问题,建议定期审查并维护此类定制化的样式规则。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值