@excalidraw/excalidraw 0.13.0-6184422 → 0.13.0-99fdffd

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -15,13 +15,22 @@ Please add the latest change on the top under the correct section.
15
15
 
16
16
  ### Features
17
17
 
18
+ - Support customization for the editor [welcome screen](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#WelcomeScreen) [#6048](https://github.com/excalidraw/excalidraw/pull/6048).
19
+
18
20
  - Expose component API for the Excalidraw main menu [#6034](https://github.com/excalidraw/excalidraw/pull/6034), You can read more about its usage [here](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#MainMenu)
19
21
 
20
- - Render Footer as a component instead of render prop [#5970](https://github.com/excalidraw/excalidraw/pull/5970). You can read more about its usage [here](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#Footer)
22
+ - Support customization for the Excalidraw [main menu](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#MainMenu) [#6034](https://github.com/excalidraw/excalidraw/pull/6034).
21
23
 
22
- #### BREAKING CHANGE
24
+ - [Footer](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#Footer) is now rendered as child component instead of passed as a render prop [#5970](https://github.com/excalidraw/excalidraw/pull/5970).
25
+
26
+ - Any top-level children passed to the `<Excalidraw/>` component that do not belong to one of the officially supported Excalidraw children components are now rendered directly inside the Excalidraw container (previously, they weren't rendered at all) [#6096](https://github.com/excalidraw/excalidraw/pull/6096).
27
+
28
+ - Expose [LiveCollaborationTrigger](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#LiveCollaborationTrigger) component. Replaces `props.onCollabButtonClick` [#6104](https://github.com/excalidraw/excalidraw/pull/6104).
29
+
30
+ #### BREAKING CHANGES
23
31
 
24
- - With this change, the prop `renderFooter` is now removed.
32
+ - `props.onCollabButtonClick` is now removed. You need to render the main menu item yourself, and optionally also render the `<LiveCollaborationTrigger>` component using [renderTopRightUI](https://github.com/excalidraw/excalidraw/blob/master/src/packages/excalidraw/README.md#renderTopRightUI) prop if you want to retain the canvas button at top-right.
33
+ - The prop `renderFooter` is now removed in favor of rendering as a child component.
25
34
 
26
35
  ### Excalidraw schema
27
36
 
package/README.md CHANGED
@@ -138,9 +138,6 @@ export default function App() {
138
138
  console.log("Elements :", elements, "State : ", state)
139
139
  }
140
140
  onPointerUpdate={(payload) => console.log(payload)}
141
- onCollabButtonClick={() =>
142
- window.alert("You clicked on collab button")
143
- }
144
141
  viewModeEnabled={viewModeEnabled}
145
142
  zenModeEnabled={zenModeEnabled}
146
143
  gridModeEnabled={gridModeEnabled}
@@ -331,7 +328,6 @@ const App = () => {
331
328
  onChange: (elements, state) =>
332
329
  console.log("Elements :", elements, "State : ", state),
333
330
  onPointerUpdate: (payload) => console.log(payload),
334
- onCollabButtonClick: () => window.alert("You clicked on collab button"),
335
331
  viewModeEnabled: viewModeEnabled,
336
332
  zenModeEnabled: zenModeEnabled,
337
333
  gridModeEnabled: gridModeEnabled,
@@ -376,7 +372,7 @@ Most notably, you can customize the primary colors, by overriding these variable
376
372
 
377
373
  For a complete list of variables, check [theme.scss](https://github.com/excalidraw/excalidraw/blob/master/src/css/theme.scss), though most of them will not make sense to override.
378
374
 
379
- ### Does this package support collaboration ?
375
+ ### Does this package support collaboration?
380
376
 
381
377
  No, Excalidraw package doesn't come with collaboration built in, since the implementation is specific to each host app. We expose APIs which you can use to communicate with Excalidraw which you can use to implement it. You can check our own implementation [here](https://github.com/excalidraw/excalidraw/blob/master/src/excalidraw-app/index.tsx).
382
378
 
@@ -405,45 +401,47 @@ const App = () => {
405
401
  };
406
402
  ```
407
403
 
408
- This will only for `Desktop` devices.
404
+ Footer is only rendered in the desktop view.
409
405
 
410
- For `mobile` you will need to render it inside the [MainMenu](#mainmenu). You can use the [`useDevice`](#useDevice) hook to check the type of device, this will be available only inside the `children` of `Excalidraw` component.
406
+ In the mobile view you can render it inside the [MainMenu](#mainmenu) (later we will expose other ways to customize the UI). You can use the [`useDevice`](#useDevice) hook to check the type of device, this will be available only inside the `children` of `Excalidraw` component.
411
407
 
412
408
  ```js
413
409
  import { useDevice, Footer } from "@excalidraw/excalidraw";
414
410
 
415
- const MobileFooter = ({
416
- }) => {
411
+ const MobileFooter = () => {
417
412
  const device = useDevice();
418
413
  if (device.isMobile) {
419
414
  return (
420
415
  <Footer>
421
- <button
422
- className="custom-footer"
423
- onClick={() => alert("This is custom footer in mobile menu")}
424
- >
425
- {" "}
426
- custom footer{" "}
427
- </button>
416
+ <button
417
+ className="custom-footer"
418
+ onClick={() => alert("This is custom footer in mobile menu")}
419
+ >
420
+ {" "}
421
+ custom footer{" "}
422
+ </button>
428
423
  </Footer>
429
424
  );
430
425
  }
431
426
  return null;
432
-
433
427
  };
428
+
434
429
  const App = () => {
435
430
  <Excalidraw>
436
431
  <MainMenu>
437
- <MainMenu.Item onSelect={() => window.alert("Item1")}> Item1 </MainMenu.Item>
438
- <MainMenu.Item onSelect={() => window.alert("Item2")}> Item 2 </>
439
- <MobileFooter/>
432
+ <MainMenu.Item onSelect={() => window.alert("Item1")}>
433
+ Item1
434
+ </MainMenu.Item>
435
+ <MainMenu.Item onSelect={() => window.alert("Item2")}>
436
+ Item2
437
+ </MainMenu.Item>
438
+ <MobileFooter />
440
439
  </MainMenu>
441
- </Excalidraw>
442
- }
443
-
440
+ </Excalidraw>;
441
+ };
444
442
  ```
445
443
 
446
- You can visit the[ example](https://ehlz3.csb.app/) for working demo.
444
+ You can visit the [example](https://ehlz3.csb.app/) for working demo.
447
445
 
448
446
  #### MainMenu
449
447
 
@@ -456,11 +454,15 @@ import { MainMenu } from "@excalidraw/excalidraw";
456
454
  const App = () => {
457
455
  <Excalidraw>
458
456
  <MainMenu>
459
- <MainMenu.Item onSelect={() => window.alert("Item1")}> Item1 </MainMenu.Item>
460
- <MainMenu.Item onSelect={() => window.alert("Item2")}> Item 2 </>
457
+ <MainMenu.Item onSelect={() => window.alert("Item1")}>
458
+ Item1
459
+ </MainMenu.Item>
460
+ <MainMenu.Item onSelect={() => window.alert("Item2")}>
461
+ Item2
462
+ </MainMenu.Item>
461
463
  </MainMenu>
462
- </Excalidraw>
463
- }
464
+ </Excalidraw>;
465
+ };
464
466
  ```
465
467
 
466
468
  **MainMenu**
@@ -469,28 +471,24 @@ This is the `MainMenu` component which you need to import to render the menu wit
469
471
 
470
472
  **MainMenu.Item**
471
473
 
472
- To render an item, its recommended to use `MainMenu.Item`.
474
+ Use this component to render a menu item.
473
475
 
474
476
  | Prop | Type | Required | Default | Description |
475
477
  | --- | --- | --- | --- | --- |
476
478
  | `onSelect` | `Function` | Yes | `undefined` | The handler is triggered when the item is selected. |
477
479
  | `children` | `React.ReactNode` | Yes | `undefined` | The content of the menu item |
478
480
  | `icon` | `JSX.Element` | No | `undefined` | The icon used in the menu item |
479
- | `shortcut` | `string` | No | `undefined` | The shortcut to be shown for the menu item |
480
- | `className` | `string` | No | "" | The class names to be added to the menu item |
481
- | `style` | `React.CSSProperties` | No | `undefined` | The inline styles to be added to the menu item |
482
- | `ariaLabel` | `string` | `undefined` | No | The `aria-label` to be added to the item for accessibility |
483
- | `dataTestId` | `string` | `undefined` | No | The `data-testid` to be added to the item. |
481
+ | `shortcut` | `string` | No | | The keyboard shortcut (label-only, does not affect behavior) |
484
482
 
485
483
  **MainMenu.ItemLink**
486
484
 
487
- To render an item as a link, its recommended to use `MainMenu.ItemLink`.
485
+ To render an external link in a menu item, you can use this component.
488
486
 
489
487
  **Usage**
490
488
 
491
489
  ```js
492
490
  import { MainMenu } from "@excalidraw/excalidraw";
493
- const App = () => {
491
+ const App = () => (
494
492
  <Excalidraw>
495
493
  <MainMenu>
496
494
  <MainMenu.ItemLink href="https://google.com">Google</MainMenu.ItemLink>
@@ -499,7 +497,7 @@ const App = () => {
499
497
  </MainMenu.ItemLink>
500
498
  </MainMenu>
501
499
  </Excalidraw>;
502
- };
500
+ );
503
501
  ```
504
502
 
505
503
  | Prop | Type | Required | Default | Description |
@@ -507,11 +505,7 @@ const App = () => {
507
505
  | `href` | `string` | Yes | `undefined` | The `href` attribute to be added to the `anchor` element. |
508
506
  | `children` | `React.ReactNode` | Yes | `undefined` | The content of the menu item |
509
507
  | `icon` | `JSX.Element` | No | `undefined` | The icon used in the menu item |
510
- | `shortcut` | `string` | No | `undefined` | The shortcut to be shown for the menu item |
511
- | `className` | `string` | No | "" | The class names to be added to the menu item |
512
- | `style` | `React.CSSProperties` | No | `undefined` | The inline styles to be added to the menu item |
513
- | `ariaLabel` | `string` | No | `undefined` | The `aria-label` to be added to the item for accessibility |
514
- | `dataTestId` | `string` | No | `undefined` | The `data-testid` to be added to the item. |
508
+ | `shortcut` | `string` | No | | The keyboard shortcut (label-only, does not affect behavior) |
515
509
 
516
510
  **MainMenu.ItemCustom**
517
511
 
@@ -521,7 +515,7 @@ To render a custom item, you can use `MainMenu.ItemCustom`.
521
515
 
522
516
  ```js
523
517
  import { MainMenu } from "@excalidraw/excalidraw";
524
- const App = () => {
518
+ const App = () => (
525
519
  <Excalidraw>
526
520
  <MainMenu>
527
521
  <MainMenu.ItemCustom>
@@ -535,15 +529,12 @@ const App = () => {
535
529
  </MainMenu.ItemCustom>
536
530
  </MainMenu>
537
531
  </Excalidraw>;
538
- };
532
+ );
539
533
  ```
540
534
 
541
535
  | Prop | Type | Required | Default | Description |
542
536
  | --- | --- | --- | --- | --- |
543
537
  | `children` | `React.ReactNode` | Yes | `undefined` | The content of the menu item |
544
- | `className` | `string` | No | "" | The class names to be added to the menu item |
545
- | `style` | `React.CSSProperties` | No | `undefined` | The inline styles to be added to the menu item |
546
- | `dataTestId` | `string` | No | `undefined` | The `data-testid` to be added to the item. |
547
538
 
548
539
  **MainMenu.DefaultItems**
549
540
 
@@ -551,7 +542,7 @@ For the items which are shown in the menu in [excalidraw.com](https://excalidraw
551
542
 
552
543
  ```js
553
544
  import { MainMenu } from "@excalidraw/excalidraw";
554
- const App = () => {
545
+ const App = () => (
555
546
  <Excalidraw>
556
547
  <MainMenu>
557
548
  <MainMenu.DefaultItems.Socials/>
@@ -560,7 +551,7 @@ const App = () => {
560
551
  <MainMenu.Item onSelect={() => window.alert("Item2")}> Item 2 </>
561
552
  </MainMenu>
562
553
  </Excalidraw>
563
- }
554
+ )
564
555
  ```
565
556
 
566
557
  Here is a [complete list](https://github.com/excalidraw/excalidraw/blob/master/src/components/mainMenu/DefaultItems.tsx) of the default items.
@@ -571,7 +562,7 @@ To Group item in the main menu, you can use `MainMenu.Group`
571
562
 
572
563
  ```js
573
564
  import { MainMenu } from "@excalidraw/excalidraw";
574
- const App = () => {
565
+ const App = () => (
575
566
  <Excalidraw>
576
567
  <MainMenu>
577
568
  <MainMenu.Group title="Excalidraw items">
@@ -584,15 +575,176 @@ const App = () => {
584
575
  </MainMenu.Group>
585
576
  </MainMenu>
586
577
  </Excalidraw>
587
- }
578
+ )
588
579
  ```
589
580
 
590
581
  | Prop | Type | Required | Default | Description |
591
582
  | --- | --- | --- | --- | --- |
592
- | `children ` | `React.ReactNode` | Yes | `undefined` | The content of the `Menu Group` |
593
- | `title` | `string` | No | `undefined` | The `title` for the grouped items |
594
- | `className` | `string` | No | "" | The `classname` to be added to the group |
595
- | `style` | `React.CSsSProperties` | No | `undefined` | The inline `styles` to be added to the group |
583
+ | `children ` | `React.ReactNode` | Yes | `undefined` | The content of the `MainMenu.Group` |
584
+
585
+ ### WelcomeScreen
586
+
587
+ When the canvas is empty, Excalidraw shows a welcome "splash" screen with a logo, a few quick action items, and hints explaining what some of the UI buttons do. You can customize the welcome screen by rendering the `WelcomeScreen` component inside your Excalidraw instance.
588
+
589
+ You can also disable the welcome screen altogether by setting `UIOptions.welcomeScreen` to `false`.
590
+
591
+ **Usage**
592
+
593
+ ```jsx
594
+ import { WelcomScreen } from "@excalidraw/excalidraw";
595
+ const App = () => (
596
+ <Excalidraw>
597
+ <WelcomeScreen>
598
+ <WelcomeScreen.Center>
599
+ <WelcomeScreen.Center.Heading>
600
+ Your data are autosaved to the cloud.
601
+ </WelcomeScreen.Center.Heading>
602
+ <WelcomeScreen.Center.Menu>
603
+ <WelcomeScreen.Center.MenuItem
604
+ onClick={() => console.log("clicked!")}
605
+ >
606
+ Click me!
607
+ </WelcomeScreen.Center.MenuItem>
608
+ <WelcomeScreen.Center.MenuItemLink href="https://github.com/excalidraw/excalidraw">
609
+ Excalidraw GitHub
610
+ </WelcomeScreen.Center.MenuItemLink>
611
+ <WelcomeScreen.Center.MenuItemHelp />
612
+ </WelcomeScreen.Center.Menu>
613
+ </WelcomeScreen.Center>
614
+ </WelcomeScreen>
615
+ </Excalidraw>
616
+ );
617
+ ```
618
+
619
+ To disable the WelcomeScreen:
620
+
621
+ ```jsx
622
+ import { WelcomScreen } from "@excalidraw/excalidraw";
623
+ const App = () => <Excalidraw UIOptions={{ welcomeScreen: false }} />;
624
+ ```
625
+
626
+ **WelcomeScreen**
627
+
628
+ If you render the `<WelcomeScreen>` component, you are responsible for rendering the content.
629
+
630
+ There are 2 main parts: 1) welcome screen center component, and 2) welcome screen hints.
631
+
632
+ ![WelcomeScreen overview](./welcome-screen-overview.png)
633
+
634
+ **WelcomeScreen.Center**
635
+
636
+ This is the center piece of the welcome screen, containing the logo, heading, and menu. All three sub-components are optional, and you can render whatever you wish into the center component.
637
+
638
+ **WelcomeScreen.Center.Logo**
639
+
640
+ By default renders the Excalidraw logo and name. Supply `children` to customize.
641
+
642
+ **WelcomeScreen.Center.Heading**
643
+
644
+ Supply `children` to change the default message.
645
+
646
+ **WelcomeScreen.Center.Menu**
647
+
648
+ Wrapper component for the menu items. You can build your menu using the `<WelcomeScreen.Center.MenuItem>` and `<WelcomeScreen.Center.MenuItemLink>` components, render your own, or render one of the default menu items.
649
+
650
+ The default menu items are:
651
+
652
+ - `<WelcomeScreen.Center.MenuItemHelp/>` - opens the help dialog.
653
+ - `<WelcomeScreen.Center.MenuItemLoadScene/>` - open the load file dialog.
654
+ - `<WelcomeScreen.Center.MenuItemLiveCollaborationTrigger/>` - intended to open the live collaboration dialog. Works similarly to [`<LiveCollaborationTrigger>`](#LiveCollaborationTrigger) and you must supply `onSelect()` handler to integrate with your collaboration implementation.
655
+
656
+ **Usage**
657
+
658
+ ```jsx
659
+ import { WelcomScreen } from "@excalidraw/excalidraw";
660
+ const App = () => (
661
+ <Excalidraw>
662
+ <WelcomeScreen>
663
+ <WelcomeScreen.Center>
664
+ <WelcomeScreen.Center.Menu>
665
+ <WelcomeScreen.Center.MenuItem
666
+ onClick={() => console.log("clicked!")}
667
+ >
668
+ Click me!
669
+ </WelcomeScreen.Center.MenuItem>
670
+ <WelcomeScreen.Center.MenuItemLink href="https://github.com/excalidraw/excalidraw">
671
+ Excalidraw GitHub
672
+ </WelcomeScreen.Center.MenuItemLink>
673
+ <WelcomeScreen.Center.MenuItemHelp />
674
+ </WelcomeScreen.Center.Menu>
675
+ </WelcomeScreen.Center>
676
+ </WelcomeScreen>
677
+ </Excalidraw>
678
+ );
679
+ ```
680
+
681
+ **WelcomeScreen.Center.MenuItem**
682
+
683
+ Use this component to render a menu item.
684
+
685
+ | Prop | Type | Required | Default | Description |
686
+ | --- | --- | --- | --- | --- |
687
+ | `onSelect` | `Function` | Yes | | The handler is triggered when the item is selected. |
688
+ | `children` | `React.ReactNode` | Yes | | The content of the menu item |
689
+ | `icon` | `JSX.Element` | No | | The icon used in the menu item |
690
+ | `shortcut` | `string` | No | | The keyboard shortcut (label-only, does not affect behavior) |
691
+
692
+ **WelcomeScreen.Center.MenuItemLink**
693
+
694
+ To render an external link in a menu item, you can use this component.
695
+
696
+ | Prop | Type | Required | Default | Description |
697
+ | --- | --- | --- | --- | --- |
698
+ | `href` | `string` | Yes | | The `href` attribute to be added to the `anchor` element. |
699
+ | `children` | `React.ReactNode` | Yes | | The content of the menu item |
700
+ | `icon` | `JSX.Element` | No | | The icon used in the menu item |
701
+ | `shortcut` | `string` | No | | The keyboard shortcut (label-only, does not affect behavior) |
702
+
703
+ **WelcomeScreen.Hints**
704
+
705
+ These subcomponents render the UI hints. Text of each hint can be customized by supplying `children`.
706
+
707
+ **WelcomeScreen.Hints.Menu**
708
+
709
+ Hint for the main menu. Supply `children` to customize the hint text.
710
+
711
+ **WelcomeScreen.Hints.Toolbar**
712
+
713
+ Hint for the toolbar. Supply `children` to customize the hint text.
714
+
715
+ **WelcomeScreen.Hints.Help**
716
+
717
+ Hint for the help dialog. Supply `children` to customize the hint text.
718
+
719
+ ### LiveCollaborationTrigger
720
+
721
+ If you implement live collaboration support and want to expose the same UI button as on excalidraw.com, you can render the `<LiveCollaborationTrigger>` component using the [renderTopRightUI](#rendertoprightui) prop. You'll need to supply `onSelect()` to handle opening of your collaboration dialog, but the button will display current `appState.collaborators` count for you.
722
+
723
+ | Prop | Type | Required | Default | Description |
724
+ | --- | --- | --- | --- | --- |
725
+ | `onSelect` | `() => any` | Yes | | Handler called when the user click on the button |
726
+ | `isCollaborating` | `boolean` | Yes | false | Whether live collaboration session is in effect. Modifies button style. |
727
+
728
+ **Usage**
729
+
730
+ ```jsx
731
+ import { LiveCollaborationTrigger } from "@excalidraw/excalidraw";
732
+ const App = () => (
733
+ <Excalidraw
734
+ renderTopRightUI={(isMobile) => {
735
+ if (isMobile) {
736
+ return null;
737
+ }
738
+ return (
739
+ <LiveCollaborationTrigger
740
+ isCollaborating={isCollaborating}
741
+ onSelect={() => setCollabDialogShown(true)}
742
+ />
743
+ );
744
+ }}
745
+ />
746
+ );
747
+ ```
596
748
 
597
749
  ### Props
598
750
 
@@ -601,7 +753,6 @@ const App = () => {
601
753
  | [`onChange`](#onChange) | Function | | This callback is triggered whenever the component updates due to any change. This callback will receive the excalidraw elements and the current app state. |
602
754
  | [`initialData`](#initialData) | <code>{elements?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/element/types.ts#L106">ExcalidrawElement[]</a>, appState?: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/types.ts#L79">AppState<a> } </code> | null | The initial data with which app loads. |
603
755
  | [`ref`](#ref) | [`createRef`](https://reactjs.org/docs/refs-and-the-dom.html#creating-refs) &#124; [`useRef`](https://reactjs.org/docs/hooks-reference.html#useref) &#124; [`callbackRef`](https://reactjs.org/docs/refs-and-the-dom.html#callback-refs) &#124; <code>{ current: { readyPromise: <a href="https://github.com/excalidraw/excalidraw/blob/master/src/utils.ts#L317">resolvablePromise</a> } }</code> | | Ref to be passed to Excalidraw |
604
- | [`onCollabButtonClick`](#onCollabButtonClick) | Function | | Callback to be triggered when the collab button is clicked |
605
756
  | [`isCollaborating`](#isCollaborating) | `boolean` | | This implies if the app is in collaboration mode |
606
757
  | [`onPointerUpdate`](#onPointerUpdate) | Function | | Callback triggered when mouse pointer is updated. |
607
758
  | [`langCode`](#langCode) | string | `en` | Language code string |
@@ -775,10 +926,6 @@ You can use this function to update the library. It accepts the below attributes
775
926
 
776
927
  Adds supplied files data to the `appState.files` cache on top of existing files present in the cache.
777
928
 
778
- #### `onCollabButtonClick`
779
-
780
- This callback is triggered when clicked on the collab button in excalidraw. If not supplied, the collab dialog button is not rendered.
781
-
782
929
  #### `isCollaborating`
783
930
 
784
931
  This prop indicates if the app is in collaboration mode.
@@ -1565,8 +1712,7 @@ This hook can be used to check the type of device which is being used. It can on
1565
1712
  ```js
1566
1713
  import { useDevice, Footer } from "@excalidraw/excalidraw";
1567
1714
 
1568
- const MobileFooter = ({
1569
- }) => {
1715
+ const MobileFooter = () => {
1570
1716
  const device = useDevice();
1571
1717
  if (device.isMobile) {
1572
1718
  return (