Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

tools-panel.tsx 5.1KB

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