@dxos/shell 0.4.10-main.c42bfdb → 0.4.10-main.c61b011

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.
Files changed (56) hide show
  1. package/dist/bundle/{index-CnChDHv2.mjs → index-BCJk2O_p.mjs} +1211 -1136
  2. package/dist/bundle/index-BCJk2O_p.mjs.map +1 -0
  3. package/dist/bundle/{index-Ba36DtoM.mjs → index-CwQjVyu5.mjs} +38 -22
  4. package/dist/bundle/index-CwQjVyu5.mjs.map +1 -0
  5. package/dist/bundle/shell.mjs +2 -3
  6. package/dist/bundle/shell.mjs.map +1 -1
  7. package/dist/bundle/shell.umd.js +43 -43
  8. package/dist/bundle/shell.umd.js.map +1 -1
  9. package/dist/bundle/style.css +1 -1
  10. package/dist/lib/browser/meta.json +1 -1
  11. package/dist/lib/browser/react.mjs +44 -40
  12. package/dist/lib/browser/react.mjs.map +3 -3
  13. package/dist/lib/browser/testing/index.mjs +3 -2
  14. package/dist/lib/browser/testing/index.mjs.map +3 -3
  15. package/dist/types/src/components/EmojiPicker.d.ts +1 -2
  16. package/dist/types/src/components/EmojiPicker.d.ts.map +1 -1
  17. package/dist/types/src/components/EmojiPicker.js.map +1 -1
  18. package/dist/types/src/components/HuePicker.d.ts +1 -2
  19. package/dist/types/src/components/HuePicker.d.ts.map +1 -1
  20. package/dist/types/src/components/HuePicker.js.map +1 -1
  21. package/dist/types/src/components/InvitationList/InvitationListItem.js +5 -5
  22. package/dist/types/src/components/InvitationList/InvitationListItem.js.map +1 -1
  23. package/dist/types/src/panels/IdentityPanel/IdentityPanel.d.ts.map +1 -1
  24. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js +9 -4
  25. package/dist/types/src/panels/IdentityPanel/IdentityPanel.js.map +1 -1
  26. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.d.ts.map +1 -1
  27. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js +5 -1
  28. package/dist/types/src/panels/IdentityPanel/useAgentHandlers.js.map +1 -1
  29. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.d.ts.map +1 -1
  30. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js +3 -1
  31. package/dist/types/src/panels/SpacePanel/steps/SpaceManager.js.map +1 -1
  32. package/dist/types/src/playwright/invitations.spec.js +3 -1
  33. package/dist/types/src/playwright/invitations.spec.js.map +1 -1
  34. package/dist/types/src/steps/InvitationManager.d.ts +1 -1
  35. package/dist/types/src/steps/InvitationManager.d.ts.map +1 -1
  36. package/dist/types/src/steps/InvitationManager.js +3 -4
  37. package/dist/types/src/steps/InvitationManager.js.map +1 -1
  38. package/dist/types/src/stories/Invitations.e2e-stories.d.ts.map +1 -1
  39. package/dist/types/src/stories/Invitations.e2e-stories.js +5 -2
  40. package/dist/types/src/stories/Invitations.e2e-stories.js.map +1 -1
  41. package/dist/types/src/testing/shell-manager.d.ts.map +1 -1
  42. package/dist/types/src/testing/shell-manager.js +3 -2
  43. package/dist/types/src/testing/shell-manager.js.map +1 -1
  44. package/package.json +23 -22
  45. package/src/components/EmojiPicker.tsx +2 -2
  46. package/src/components/HuePicker.tsx +2 -2
  47. package/src/components/InvitationList/InvitationListItem.tsx +5 -5
  48. package/src/panels/IdentityPanel/IdentityPanel.tsx +10 -4
  49. package/src/panels/IdentityPanel/useAgentHandlers.ts +5 -1
  50. package/src/panels/SpacePanel/steps/SpaceManager.tsx +3 -1
  51. package/src/playwright/invitations.spec.ts +3 -1
  52. package/src/steps/InvitationManager.tsx +4 -4
  53. package/src/stories/Invitations.e2e-stories.tsx +6 -3
  54. package/src/testing/shell-manager.ts +3 -2
  55. package/dist/bundle/index-Ba36DtoM.mjs.map +0 -1
  56. package/dist/bundle/index-CnChDHv2.mjs.map +0 -1
@@ -712,13 +712,13 @@ var AvatarStackEffect = ({ animation, status, reverseEffects }) => {
712
712
  };
713
713
  var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationStatus, send, onClickRemove, createInvitationUrl, reverseEffects, ...props }) => {
714
714
  const { t } = useTranslation8("os");
715
- const { cancel, status: invitationStatus, invitationCode, authCode, type } = propsInvitationStatus;
715
+ const { cancel, status: invitationStatus, invitationCode, authCode, multiUse } = propsInvitationStatus;
716
716
  const isCancellable = !([
717
717
  Invitation.State.ERROR,
718
718
  Invitation.State.TIMEOUT,
719
719
  Invitation.State.CANCELLED
720
720
  ].indexOf(invitationStatus) >= 0);
721
- const showShare = type === Invitation.Type.MULTIUSE || [
721
+ const showShare = multiUse || [
722
722
  Invitation.State.INIT,
723
723
  Invitation.State.CONNECTING,
724
724
  Invitation.State.CONNECTED
@@ -762,7 +762,7 @@ var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationSta
762
762
  ]
763
763
  }, /* @__PURE__ */ React12.createElement(ListItem3.Heading, {
764
764
  classNames: "sr-only"
765
- }, t(type === Invitation.Type.MULTIUSE ? "invite many list item label" : "invite one list item label")), type === Invitation.Type.MULTIUSE && /* @__PURE__ */ React12.createElement(AvatarStackEffect, {
765
+ }, t(multiUse ? "invite many list item label" : "invite one list item label")), multiUse && /* @__PURE__ */ React12.createElement(AvatarStackEffect, {
766
766
  status: avatarStatus,
767
767
  animation: avatarAnimation,
768
768
  reverseEffects
@@ -783,7 +783,7 @@ var InvitationListItemImpl = ({ invitation, invitationStatus: propsInvitationSta
783
783
  })))), /* @__PURE__ */ React12.createElement(Tooltip5.Portal, null, /* @__PURE__ */ React12.createElement(Tooltip5.Content, {
784
784
  side: "left",
785
785
  classNames: "z-[70]"
786
- }, t(type === Invitation.Type.MULTIUSE ? "invite many qr label" : "invite one qr label"), /* @__PURE__ */ React12.createElement(Tooltip5.Arrow, null)))), showShare && invitationUrl ? /* @__PURE__ */ React12.createElement(Tooltip5.Root, null, /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(Tooltip5.Trigger, {
786
+ }, t(multiUse ? "invite many qr label" : "invite one qr label"), /* @__PURE__ */ React12.createElement(Tooltip5.Arrow, null)))), showShare && invitationUrl ? /* @__PURE__ */ React12.createElement(Tooltip5.Root, null, /* @__PURE__ */ React12.createElement(React12.Fragment, null, /* @__PURE__ */ React12.createElement(Tooltip5.Trigger, {
787
787
  asChild: true
788
788
  }, /* @__PURE__ */ React12.createElement(Button7, {
789
789
  variant: "ghost",
@@ -1425,8 +1425,9 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1425
1425
  const onAgentCreate = async () => {
1426
1426
  invitations.forEach((invitation2) => invitation2.cancel());
1427
1427
  const invitation = client.halo.share({
1428
- type: Invitation3.Type.MULTIUSE,
1429
- authMethod: Invitation3.AuthMethod.NONE
1428
+ type: Invitation3.Type.INTERACTIVE,
1429
+ authMethod: Invitation3.AuthMethod.NONE,
1430
+ multiUse: true
1430
1431
  });
1431
1432
  invitation.subscribe(handleAgentCreate);
1432
1433
  };
@@ -1434,7 +1435,7 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1434
1435
  const identity2 = client.halo.identity.get();
1435
1436
  invariant(identity2, "Identity not found", {
1436
1437
  F: __dxlog_file3,
1437
- L: 77,
1438
+ L: 81,
1438
1439
  S: void 0,
1439
1440
  A: [
1440
1441
  "identity",
@@ -1463,7 +1464,6 @@ var useAgentHandlers = ({ client, invitations, identity }) => {
1463
1464
  import { Check as Check4, X as X3 } from "@phosphor-icons/react";
1464
1465
  import React27, { useMemo as useMemo2 } from "react";
1465
1466
  import { QR } from "react-qr-rounded";
1466
- import { Invitation as Invitation5 } from "@dxos/react-client/invitations";
1467
1467
  import { useId as useId5, useTranslation as useTranslation12 } from "@dxos/react-ui";
1468
1468
  import { descriptionText as descriptionText8, getSize as getSize11, mx as mx20 } from "@dxos/react-ui-theme";
1469
1469
  import { hexToEmoji as hexToEmoji3 } from "@dxos/util";
@@ -1516,10 +1516,10 @@ var InvitationManagerView = ({ children, ...props }) => {
1516
1516
  classNames: "grow flex flex-col justify-around items-center"
1517
1517
  }, children);
1518
1518
  };
1519
- var InvitationManager = ({ invitationUrl, active, send, status, type, authCode, id = "0" }) => {
1519
+ var InvitationManager = ({ invitationUrl, active, send, status, multiUse, authCode, id = "0" }) => {
1520
1520
  const { t } = useTranslation12("os");
1521
1521
  const qrLabel = useId5("invitation-manager__qr-code");
1522
- const statusValue = type === Invitation5.Type.MULTIUSE ? 0 : invitationStatusValue.get(status) ?? 0;
1522
+ const statusValue = multiUse ? 0 : invitationStatusValue.get(status) ?? 0;
1523
1523
  const showAuthCode = statusValue === 3;
1524
1524
  const emoji = hexToEmoji3(id);
1525
1525
  const activeView = useMemo2(() => {
@@ -1543,7 +1543,7 @@ var InvitationManager = ({ invitationUrl, active, send, status, type, authCode,
1543
1543
  emoji
1544
1544
  }, /* @__PURE__ */ React27.createElement("p", {
1545
1545
  className: "text-sm mlb-1 font-normal text-center"
1546
- }, t(type === Invitation5.Type.MULTIUSE ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React27.createElement("div", {
1546
+ }, t(multiUse ? "invite many qr label" : "invite one qr label")), /* @__PURE__ */ React27.createElement("div", {
1547
1547
  role: "none",
1548
1548
  className: mx20(descriptionText8, "is-full max-is-[14rem] relative")
1549
1549
  }, /* @__PURE__ */ React27.createElement(QR, {
@@ -1663,8 +1663,8 @@ var IdentityHeading = ({ titleId, title, identity, onDone, onUpdateProfile, conn
1663
1663
  const fallbackValue = keyToFallback3(identity.identityKey);
1664
1664
  const { t } = useTranslation14("os");
1665
1665
  const [displayName, setDisplayName] = useState8(identity.profile?.displayName ?? "");
1666
- const [emoji, setEmoji] = useState8(getEmojiValue(identity));
1667
- const [hue, setHue] = useState8(getHueValue(identity));
1666
+ const [emoji, setEmojiDirectly] = useState8(getEmojiValue(identity));
1667
+ const [hue, setHueDirectly] = useState8(getHueValue(identity));
1668
1668
  const { textValue, setTextValue } = useClipboardContext();
1669
1669
  const identityHex = identity.identityKey.toHex();
1670
1670
  const copied = textValue === identityHex;
@@ -1686,12 +1686,14 @@ var IdentityHeading = ({ titleId, title, identity, onDone, onUpdateProfile, conn
1686
1686
  };
1687
1687
  return onUpdateProfile?.(nextProfile);
1688
1688
  };
1689
- useEffect3(() => {
1689
+ const setEmoji = (nextEmoji) => {
1690
+ setEmojiDirectly(nextEmoji);
1690
1691
  void handleUpdateProfile();
1691
- }, [
1692
- emoji,
1693
- hue
1694
- ]);
1692
+ };
1693
+ const setHue = (nextHue) => {
1694
+ setHueDirectly(nextHue);
1695
+ void handleUpdateProfile();
1696
+ };
1695
1697
  const isConnected = connectionState === ConnectionState.ONLINE;
1696
1698
  return /* @__PURE__ */ React29.createElement(Heading, {
1697
1699
  titleId,
@@ -1843,7 +1845,7 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1843
1845
  if (!identity) {
1844
1846
  log6.error("IdentityPanel rendered with no active identity.", void 0, {
1845
1847
  F: __dxlog_file5,
1846
- L: 234,
1848
+ L: 240,
1847
1849
  S: void 0,
1848
1850
  C: (f, a) => f(...a)
1849
1851
  });
@@ -1860,7 +1862,7 @@ var IdentityPanel = ({ titleId: propsTitleId, createInvitationUrl = (code) => co
1860
1862
  const subscription = identityService.subscribe((state) => {
1861
1863
  log6("[state]", state, {
1862
1864
  F: __dxlog_file5,
1863
- L: 247,
1865
+ L: 253,
1864
1866
  S: void 0,
1865
1867
  C: (f, a) => f(...a)
1866
1868
  });
@@ -1956,7 +1958,7 @@ import { useCallback as useCallback6 } from "react";
1956
1958
  import { assign as assign2, createMachine as createMachine2 } from "xstate";
1957
1959
  import { log as log7 } from "@dxos/log";
1958
1960
  import { AlreadyJoinedError } from "@dxos/react-client";
1959
- import { Invitation as Invitation6, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
1961
+ import { Invitation as Invitation5, InvitationEncoder as InvitationEncoder3 } from "@dxos/react-client/invitations";
1960
1962
  var __dxlog_file6 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/joinMachine.ts";
1961
1963
  var getInvitationSubscribable = (Kind, invitation) => {
1962
1964
  log7("[subscribing to invitation]", invitation, {
@@ -1968,7 +1970,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
1968
1970
  return {
1969
1971
  subscribe: (next, onError, complete) => invitation.subscribe((invitation2) => {
1970
1972
  switch (invitation2.state) {
1971
- case Invitation6.State.CONNECTING: {
1973
+ case Invitation5.State.CONNECTING: {
1972
1974
  log7("[invitation connecting]", {
1973
1975
  Kind,
1974
1976
  invitation: invitation2
@@ -1983,7 +1985,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
1983
1985
  invitation: invitation2
1984
1986
  });
1985
1987
  }
1986
- case Invitation6.State.CONNECTED: {
1988
+ case Invitation5.State.CONNECTED: {
1987
1989
  log7("[invitation connected]", {
1988
1990
  Kind,
1989
1991
  invitation: invitation2
@@ -1998,7 +2000,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
1998
2000
  invitation: invitation2
1999
2001
  });
2000
2002
  }
2001
- case Invitation6.State.READY_FOR_AUTHENTICATION: {
2003
+ case Invitation5.State.READY_FOR_AUTHENTICATION: {
2002
2004
  log7("[invitation ready for authentication]", {
2003
2005
  Kind,
2004
2006
  invitation: invitation2
@@ -2013,7 +2015,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
2013
2015
  invitation: invitation2
2014
2016
  });
2015
2017
  }
2016
- case Invitation6.State.AUTHENTICATING: {
2018
+ case Invitation5.State.AUTHENTICATING: {
2017
2019
  log7("[invitation authenticating]", {
2018
2020
  Kind,
2019
2021
  invitation: invitation2
@@ -2028,7 +2030,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
2028
2030
  invitation: invitation2
2029
2031
  });
2030
2032
  }
2031
- case Invitation6.State.SUCCESS: {
2033
+ case Invitation5.State.SUCCESS: {
2032
2034
  log7("[invitation success]", {
2033
2035
  Kind,
2034
2036
  invitation: invitation2
@@ -2044,7 +2046,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
2044
2046
  });
2045
2047
  return complete?.();
2046
2048
  }
2047
- case Invitation6.State.CANCELLED: {
2049
+ case Invitation5.State.CANCELLED: {
2048
2050
  log7.warn("[invitation cancelled]", {
2049
2051
  Kind
2050
2052
  }, {
@@ -2058,7 +2060,7 @@ var getInvitationSubscribable = (Kind, invitation) => {
2058
2060
  reason: "cancelled"
2059
2061
  });
2060
2062
  }
2061
- case Invitation6.State.TIMEOUT: {
2063
+ case Invitation5.State.TIMEOUT: {
2062
2064
  log7.error("[invitation timeout]", {
2063
2065
  Kind
2064
2066
  }, {
@@ -2157,7 +2159,7 @@ var acceptingInvitationTemplate = (Kind, successTarget) => {
2157
2159
  {
2158
2160
  cond: (context) => {
2159
2161
  const invitation = context[Kind.toLowerCase()].invitation;
2160
- return !invitation || invitation?.state === Invitation6.State.CONNECTING;
2162
+ return !invitation || invitation?.state === Invitation5.State.CONNECTING;
2161
2163
  },
2162
2164
  target: `connecting${Kind}Invitation`,
2163
2165
  actions: "log"
@@ -2936,7 +2938,7 @@ var InvitationAuthenticator = ({ failed, Kind, active, pending, invitationId, on
2936
2938
  var stepStyles = "pbs-1 pbe-3 pli-3";
2937
2939
 
2938
2940
  // packages/sdk/shell/src/styles/invitationStatusStyles.ts
2939
- import { Invitation as Invitation7 } from "@dxos/react-client/invitations";
2941
+ import { Invitation as Invitation6 } from "@dxos/react-client/invitations";
2940
2942
  var inactiveBgColor = "bg-neutral-100 dark:bg-neutral-600";
2941
2943
  var activeBgColor = "bg-primary-500 dark:bg-primary-400";
2942
2944
  var successBgColor = "bg-success-500 dark:bg-success-400";
@@ -2952,9 +2954,9 @@ var activeStrokeColor = "stroke-primary-400 dark:stroke-primary-150";
2952
2954
  var successStrokeColor = "stroke-success-300 dark:stroke-primary-400";
2953
2955
  var errorStrokeColor = "stroke-error-300 dark:stroke-error-500";
2954
2956
  var cancelledStrokeColor = "stroke-warning-300 dark:stroke-warning-500";
2955
- var resolvedStrokeColor = (status) => status === Invitation7.State.ERROR ? errorStrokeColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledStrokeColor : successStrokeColor;
2956
- var resolvedBgColor = (status) => status === Invitation7.State.ERROR ? errorBgColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledBgColor : successBgColor;
2957
- var resolvedTextColor = (status) => status === Invitation7.State.ERROR ? errorTextColor : status === Invitation7.State.CANCELLED || status === Invitation7.State.TIMEOUT ? cancelledTextColor : successTextColor;
2957
+ var resolvedStrokeColor = (status) => status === Invitation6.State.ERROR ? errorStrokeColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledStrokeColor : successStrokeColor;
2958
+ var resolvedBgColor = (status) => status === Invitation6.State.ERROR ? errorBgColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledBgColor : successBgColor;
2959
+ var resolvedTextColor = (status) => status === Invitation6.State.ERROR ? errorTextColor : status === Invitation6.State.CANCELLED || status === Invitation6.State.TIMEOUT ? cancelledTextColor : successTextColor;
2958
2960
 
2959
2961
  // packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx
2960
2962
  var __dxlog_file9 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/JoinPanel/JoinPanel.tsx";
@@ -3454,7 +3456,7 @@ import React39, { useCallback as useCallback8, useState as useState12 } from "re
3454
3456
  import { log as log12 } from "@dxos/log";
3455
3457
  import { useConfig } from "@dxos/react-client";
3456
3458
  import { useSpaceInvitations as useSpaceInvitations2 } from "@dxos/react-client/echo";
3457
- import { Invitation as Invitation8, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3459
+ import { Invitation as Invitation7, InvitationEncoder as InvitationEncoder4 } from "@dxos/react-client/invitations";
3458
3460
  import { ScrollArea, useTranslation as useTranslation23 } from "@dxos/react-ui";
3459
3461
  import { descriptionText as descriptionText11, mx as mx24 } from "@dxos/react-ui-theme";
3460
3462
  var __dxlog_file11 = "/home/runner/work/dxos/dxos/packages/sdk/shell/src/panels/SpacePanel/steps/SpaceManager.tsx";
@@ -3466,7 +3468,7 @@ var SpaceManager = (props) => {
3466
3468
  const invitations = useSpaceInvitations2(space?.key);
3467
3469
  const onInvitationEvent = useCallback8((invitation) => {
3468
3470
  const invitationCode = InvitationEncoder4.encode(invitation);
3469
- if (invitation.state === Invitation8.State.CONNECTING) {
3471
+ if (invitation.state === Invitation7.State.CONNECTING) {
3470
3472
  log12.info(JSON.stringify({
3471
3473
  invitationCode,
3472
3474
  authCode: invitation.authCode
@@ -3485,8 +3487,9 @@ var SpaceManager = (props) => {
3485
3487
  icon: UserPlus,
3486
3488
  onClick: useCallback8(() => {
3487
3489
  const invitation = space.share?.({
3488
- type: Invitation8.Type.INTERACTIVE,
3489
- authMethod: Invitation8.AuthMethod.SHARED_SECRET,
3490
+ type: Invitation7.Type.INTERACTIVE,
3491
+ authMethod: Invitation7.AuthMethod.SHARED_SECRET,
3492
+ multiUse: false,
3490
3493
  target
3491
3494
  });
3492
3495
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
@@ -3502,8 +3505,9 @@ var SpaceManager = (props) => {
3502
3505
  icon: UsersThree,
3503
3506
  onClick: useCallback8(() => {
3504
3507
  const invitation = space.share?.({
3505
- type: Invitation8.Type.MULTIUSE,
3506
- authMethod: Invitation8.AuthMethod.NONE,
3508
+ type: Invitation7.Type.INTERACTIVE,
3509
+ authMethod: Invitation7.AuthMethod.NONE,
3510
+ multiUse: true,
3507
3511
  target
3508
3512
  });
3509
3513
  if (invitation && config.values.runtime?.app?.env?.DX_ENVIRONMENT !== "production") {
@@ -3539,7 +3543,7 @@ var SpaceManagerImpl = (props) => {
3539
3543
  localStorage.setItem(activeActionKey, nextAction);
3540
3544
  };
3541
3545
  const visibleInvitations = showInactiveInvitations ? invitations : invitations?.filter((invitation) => ![
3542
- Invitation8.State.CANCELLED
3546
+ Invitation7.State.CANCELLED
3543
3547
  ].includes(invitation.get().state));
3544
3548
  return /* @__PURE__ */ React39.createElement(React39.Fragment, null, /* @__PURE__ */ React39.createElement(ScrollArea.Root, {
3545
3549
  classNames: "grow shrink basis-28 -mli-2"