upload.py 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. """A file upload component."""
  2. from typing import Dict, List, Optional
  3. from pynecone.components.component import EVENT_ARG, Component
  4. from pynecone.components.forms.input import Input
  5. from pynecone.components.layout.box import Box
  6. from pynecone.event import EventChain
  7. from pynecone.var import BaseVar, Var
  8. upload_file = BaseVar(name="e => File(e)", type_=EventChain)
  9. class Upload(Component):
  10. """A file upload component."""
  11. library = "react-dropzone"
  12. tag = "ReactDropzone"
  13. # The list of accepted file types. This should be a dictionary of MIME types as keys and array of file formats as
  14. # values.
  15. # supported MIME types: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
  16. accept: Var[Optional[Dict[str, List]]]
  17. # Whether the dropzone is disabled.
  18. disabled: Var[bool]
  19. # The maximum number of files that can be uploaded.
  20. max_files: Var[int]
  21. # The maximum file size (bytes) that can be uploaded.
  22. max_size: Var[int]
  23. # The minimum file size (bytes) that can be uploaded.
  24. min_size: Var[int]
  25. # Whether to allow multiple files to be uploaded.
  26. multiple: Var[bool] = True # type: ignore
  27. # Whether to disable click to upload.
  28. no_click: Var[bool]
  29. # Whether to disable drag and drop.
  30. no_drag: Var[bool]
  31. # Whether to disable using the space/enter keys to upload.
  32. no_keyboard: Var[bool]
  33. @classmethod
  34. def create(cls, *children, **props) -> Component:
  35. """Create an upload component.
  36. Args:
  37. children: The children of the component.
  38. props: The properties of the component.
  39. Returns:
  40. The upload component.
  41. """
  42. # get only upload component props
  43. supported_props = cls.get_props()
  44. upload_props = {
  45. key: value for key, value in props.items() if key in supported_props
  46. }
  47. # The file input to use.
  48. upload = Input.create(type_="file")
  49. upload.special_props = {BaseVar(name="{...getInputProps()}", type_=None)}
  50. # The dropzone to use.
  51. zone = Box.create(
  52. upload,
  53. *children,
  54. **{k: v for k, v in props.items() if k not in supported_props}
  55. )
  56. zone.special_props = {BaseVar(name="{...getRootProps()}", type_=None)}
  57. # Create the component.
  58. return super().create(zone, on_drop=upload_file, **upload_props)
  59. @classmethod
  60. def get_controlled_triggers(cls) -> Dict[str, Var]:
  61. """Get the event triggers that pass the component's value to the handler.
  62. Returns:
  63. A dict mapping the event trigger to the var that is passed to the handler.
  64. """
  65. return {
  66. "on_drop": EVENT_ARG,
  67. }
  68. def _render(self):
  69. out = super()._render()
  70. out.args = ("getRootProps", "getInputProps")
  71. return out