您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

shapes-functions.tsx 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import { IconButton, breakpoints } from 'components/shared'
  2. import { memo } from 'react'
  3. import styled from 'styles'
  4. import { MoveType } from 'types'
  5. import { Trash2 } from 'react-feather'
  6. import state, { useSelector } from 'state'
  7. import Tooltip from 'components/tooltip'
  8. import {
  9. ArrowDownIcon,
  10. ArrowUpIcon,
  11. AspectRatioIcon,
  12. BoxIcon,
  13. CopyIcon,
  14. EyeClosedIcon,
  15. EyeOpenIcon,
  16. LockClosedIcon,
  17. LockOpen1Icon,
  18. PinBottomIcon,
  19. PinTopIcon,
  20. RotateCounterClockwiseIcon,
  21. } from '@radix-ui/react-icons'
  22. import { getPage, getSelectedIds } from 'utils'
  23. function handleRotateCcw() {
  24. state.send('ROTATED_CCW')
  25. }
  26. function handleDuplicate() {
  27. state.send('DUPLICATED')
  28. }
  29. function handleHide() {
  30. state.send('TOGGLED_SHAPE_HIDE')
  31. }
  32. function handleLock() {
  33. state.send('TOGGLED_SHAPE_LOCK')
  34. }
  35. function handleAspectLock() {
  36. state.send('TOGGLED_SHAPE_ASPECT_LOCK')
  37. }
  38. function handleMoveToBack() {
  39. state.send('MOVED', { type: MoveType.ToBack })
  40. }
  41. function handleMoveBackward() {
  42. state.send('MOVED', { type: MoveType.Backward })
  43. }
  44. function handleMoveForward() {
  45. state.send('MOVED', { type: MoveType.Forward })
  46. }
  47. function handleMoveToFront() {
  48. state.send('MOVED', { type: MoveType.ToFront })
  49. }
  50. function handleDelete() {
  51. state.send('DELETED')
  52. }
  53. function ShapesFunctions() {
  54. const isAllLocked = useSelector((s) => {
  55. const page = getPage(s.data)
  56. return s.values.selectedIds.every((id) => page.shapes[id].isLocked)
  57. })
  58. const isAllAspectLocked = useSelector((s) => {
  59. const page = getPage(s.data)
  60. return s.values.selectedIds.every(
  61. (id) => page.shapes[id].isAspectRatioLocked
  62. )
  63. })
  64. const isAllHidden = useSelector((s) => {
  65. const page = getPage(s.data)
  66. return s.values.selectedIds.every((id) => page.shapes[id].isHidden)
  67. })
  68. const hasSelection = useSelector((s) => {
  69. return getSelectedIds(s.data).size > 0
  70. })
  71. return (
  72. <>
  73. <ButtonsRow>
  74. <IconButton
  75. bp={breakpoints}
  76. disabled={!hasSelection}
  77. size="small"
  78. onClick={handleDuplicate}
  79. >
  80. <Tooltip label="Duplicate">
  81. <CopyIcon />
  82. </Tooltip>
  83. </IconButton>
  84. <IconButton
  85. disabled={!hasSelection}
  86. size="small"
  87. onClick={handleRotateCcw}
  88. >
  89. <Tooltip label="Rotate">
  90. <RotateCounterClockwiseIcon />
  91. </Tooltip>
  92. </IconButton>
  93. <IconButton
  94. bp={breakpoints}
  95. disabled={!hasSelection}
  96. size="small"
  97. onClick={handleHide}
  98. >
  99. <Tooltip label="Toogle Hidden">
  100. {isAllHidden ? <EyeClosedIcon /> : <EyeOpenIcon />}
  101. </Tooltip>
  102. </IconButton>
  103. <IconButton
  104. bp={breakpoints}
  105. disabled={!hasSelection}
  106. size="small"
  107. onClick={handleLock}
  108. >
  109. <Tooltip label="Toogle Locked">
  110. {isAllLocked ? <LockClosedIcon /> : <LockOpen1Icon />}
  111. </Tooltip>
  112. </IconButton>
  113. <IconButton
  114. bp={breakpoints}
  115. disabled={!hasSelection}
  116. size="small"
  117. onClick={handleAspectLock}
  118. >
  119. <Tooltip label="Toogle Aspect Ratio Lock">
  120. {isAllAspectLocked ? <AspectRatioIcon /> : <BoxIcon />}
  121. </Tooltip>
  122. </IconButton>
  123. </ButtonsRow>
  124. <ButtonsRow>
  125. <IconButton
  126. bp={breakpoints}
  127. disabled={!hasSelection}
  128. size="small"
  129. onClick={handleMoveToBack}
  130. >
  131. <Tooltip label="Move to Back">
  132. <PinBottomIcon />
  133. </Tooltip>
  134. </IconButton>
  135. <IconButton
  136. bp={breakpoints}
  137. disabled={!hasSelection}
  138. size="small"
  139. onClick={handleMoveBackward}
  140. >
  141. <Tooltip label="Move Backward">
  142. <ArrowDownIcon />
  143. </Tooltip>
  144. </IconButton>
  145. <IconButton
  146. bp={breakpoints}
  147. disabled={!hasSelection}
  148. size="small"
  149. onClick={handleMoveForward}
  150. >
  151. <Tooltip label="Move Forward">
  152. <ArrowUpIcon />
  153. </Tooltip>
  154. </IconButton>
  155. <IconButton
  156. bp={breakpoints}
  157. disabled={!hasSelection}
  158. size="small"
  159. onClick={handleMoveToFront}
  160. >
  161. <Tooltip label="More to Front">
  162. <PinTopIcon />
  163. </Tooltip>
  164. </IconButton>
  165. <IconButton
  166. bp={breakpoints}
  167. disabled={!hasSelection}
  168. size="small"
  169. onClick={handleDelete}
  170. >
  171. <Tooltip label="Delete">
  172. <Trash2 size="15" />
  173. </Tooltip>
  174. </IconButton>
  175. </ButtonsRow>
  176. </>
  177. )
  178. }
  179. export default memo(ShapesFunctions)
  180. const ButtonsRow = styled('div', {
  181. position: 'relative',
  182. display: 'flex',
  183. width: '100%',
  184. background: 'none',
  185. border: 'none',
  186. cursor: 'pointer',
  187. outline: 'none',
  188. alignItems: 'center',
  189. justifyContent: 'flex-start',
  190. padding: 4,
  191. })