You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

tools-panel.tsx 4.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. import {
  2. ArrowTopRightIcon,
  3. CircleIcon,
  4. CursorArrowIcon,
  5. LockClosedIcon,
  6. LockOpen1Icon,
  7. Pencil1Icon,
  8. SquareIcon,
  9. TextIcon,
  10. } from '@radix-ui/react-icons'
  11. import { PrimaryButton, SecondaryButton } from './shared'
  12. import { FloatingContainer } from '../shared'
  13. import React from 'react'
  14. import state, { useSelector } from 'state'
  15. import styled from 'styles'
  16. import { ShapeType } from 'types'
  17. import UndoRedo from './undo-redo'
  18. import Zoom from './zoom'
  19. const selectArrowTool = () => state.send('SELECTED_ARROW_TOOL')
  20. const selectDrawTool = () => state.send('SELECTED_DRAW_TOOL')
  21. const selectEllipseTool = () => state.send('SELECTED_ELLIPSE_TOOL')
  22. const selectTextTool = () => state.send('SELECTED_TEXT_TOOL')
  23. const selectRectangleTool = () => state.send('SELECTED_RECTANGLE_TOOL')
  24. const selectSelectTool = () => state.send('SELECTED_SELECT_TOOL')
  25. const toggleToolLock = () => state.send('TOGGLED_TOOL_LOCK')
  26. export default function ToolsPanel(): JSX.Element {
  27. const activeTool = useSelector((s) => s.data.activeTool)
  28. const isToolLocked = useSelector((s) => s.data.settings.isToolLocked)
  29. return (
  30. <ToolsPanelContainer>
  31. <LeftWrap size={{ '@initial': 'mobile', '@sm': 'small' }}>
  32. <Zoom />
  33. <FloatingContainer>
  34. <SecondaryButton
  35. label={'Select'}
  36. onClick={selectSelectTool}
  37. isActive={activeTool === 'select'}
  38. >
  39. <CursorArrowIcon />
  40. </SecondaryButton>
  41. </FloatingContainer>
  42. </LeftWrap>
  43. <CenterWrap>
  44. <FloatingContainer>
  45. <PrimaryButton
  46. label={ShapeType.Draw}
  47. onClick={selectDrawTool}
  48. isActive={activeTool === ShapeType.Draw}
  49. >
  50. <Pencil1Icon />
  51. </PrimaryButton>
  52. <PrimaryButton
  53. label={ShapeType.Rectangle}
  54. onClick={selectRectangleTool}
  55. isActive={activeTool === ShapeType.Rectangle}
  56. >
  57. <SquareIcon />
  58. </PrimaryButton>
  59. <PrimaryButton
  60. label={ShapeType.Ellipse}
  61. onClick={selectEllipseTool}
  62. isActive={activeTool === ShapeType.Ellipse}
  63. >
  64. <CircleIcon />
  65. </PrimaryButton>
  66. <PrimaryButton
  67. label={ShapeType.Arrow}
  68. onClick={selectArrowTool}
  69. isActive={activeTool === ShapeType.Arrow}
  70. >
  71. <ArrowTopRightIcon />
  72. </PrimaryButton>
  73. <PrimaryButton
  74. label={ShapeType.Text}
  75. onClick={selectTextTool}
  76. isActive={activeTool === ShapeType.Text}
  77. >
  78. <TextIcon />
  79. </PrimaryButton>
  80. </FloatingContainer>
  81. </CenterWrap>
  82. <RightWrap size={{ '@initial': 'mobile', '@sm': 'small' }}>
  83. <FloatingContainer>
  84. <SecondaryButton
  85. label={'Lock Tool'}
  86. onClick={toggleToolLock}
  87. isActive={isToolLocked}
  88. >
  89. {isToolLocked ? <LockClosedIcon /> : <LockOpen1Icon />}
  90. </SecondaryButton>
  91. </FloatingContainer>
  92. <UndoRedo />
  93. </RightWrap>
  94. </ToolsPanelContainer>
  95. )
  96. }
  97. const ToolsPanelContainer = styled('div', {
  98. position: 'fixed',
  99. bottom: 44,
  100. left: 0,
  101. right: 0,
  102. width: '100%',
  103. minWidth: 0,
  104. maxWidth: '100%',
  105. display: 'grid',
  106. gridTemplateColumns: '1fr auto 1fr',
  107. padding: '0 8px 12px 8px',
  108. alignItems: 'flex-end',
  109. zIndex: 200,
  110. gap: 12,
  111. })
  112. const CenterWrap = styled('div', {
  113. gridRow: 1,
  114. gridColumn: 2,
  115. display: 'flex',
  116. width: 'fit-content',
  117. justifyContent: 'center',
  118. })
  119. const LeftWrap = styled('div', {
  120. gridRow: 1,
  121. gridColumn: 1,
  122. display: 'flex',
  123. variants: {
  124. size: {
  125. mobile: {
  126. flexDirection: 'column',
  127. justifyContent: 'flex-end',
  128. alignItems: 'flex-start',
  129. '& > *:nth-of-type(1)': {
  130. marginBottom: '8px',
  131. },
  132. },
  133. small: {
  134. flexDirection: 'row',
  135. alignItems: 'flex-end',
  136. justifyContent: 'space-between',
  137. '& > *:nth-of-type(1)': {
  138. marginBottom: '0px',
  139. },
  140. },
  141. },
  142. },
  143. })
  144. const RightWrap = styled('div', {
  145. gridRow: 1,
  146. gridColumn: 3,
  147. display: 'flex',
  148. variants: {
  149. size: {
  150. mobile: {
  151. flexDirection: 'column-reverse',
  152. justifyContent: 'flex-end',
  153. alignItems: 'flex-end',
  154. '& > *:nth-of-type(2)': {
  155. marginBottom: '8px',
  156. },
  157. },
  158. small: {
  159. flexDirection: 'row',
  160. alignItems: 'flex-end',
  161. justifyContent: 'space-between',
  162. '& > *:nth-of-type(2)': {
  163. marginBottom: '0px',
  164. },
  165. },
  166. },
  167. },
  168. })