@crystallize/design-system 1.11.2 → 1.11.4

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
@@ -1,5 +1,17 @@
1
1
  # @crystallize/design-system
2
2
 
3
+ ## 1.11.4
4
+
5
+ ### Patch Changes
6
+
7
+ - 1bb27da: Add portal component to the ActionMenu and data-testid property
8
+
9
+ ## 1.11.3
10
+
11
+ ### Patch Changes
12
+
13
+ - 7b69e70: Replace old colors classes with the proper ones
14
+
3
15
  ## 1.11.2
4
16
 
5
17
  ### Patch Changes
package/dist/index.css CHANGED
@@ -640,6 +640,9 @@ button {
640
640
  .h-full {
641
641
  height: 100%;
642
642
  }
643
+ .w-1\/2 {
644
+ width: 50%;
645
+ }
643
646
  .w-4 {
644
647
  width: 1rem;
645
648
  }
@@ -808,6 +811,10 @@ button {
808
811
  --tw-bg-opacity: 1 !important;
809
812
  background-color: rgb(var(--c-color-purple-50-900) / var(--tw-bg-opacity)) !important;
810
813
  }
814
+ .bg-elevate {
815
+ --tw-bg-opacity: 1;
816
+ background-color: rgb(var(--c-color-elevate) / var(--tw-bg-opacity));
817
+ }
811
818
  .bg-gray {
812
819
  background-color: rgb(var(--c-color-gray));
813
820
  }
@@ -823,10 +830,6 @@ button {
823
830
  --tw-bg-opacity: 1;
824
831
  background-color: rgb(var(--c-color-purple-50-900) / var(--tw-bg-opacity));
825
832
  }
826
- .bg-white {
827
- --tw-bg-opacity: 1;
828
- background-color: rgb(255 255 255 / var(--tw-bg-opacity));
829
- }
830
833
  .bg-\[length\:16px_16px\] {
831
834
  background-size: 16px 16px;
832
835
  }
@@ -878,6 +881,9 @@ button {
878
881
  padding-top: 0.5rem;
879
882
  padding-bottom: 0.5rem;
880
883
  }
884
+ .pt-14 {
885
+ padding-top: 3.5rem;
886
+ }
881
887
  .text-center {
882
888
  text-align: center;
883
889
  }
@@ -1199,8 +1205,6 @@ button {
1199
1205
  /* src/action-menu/action-menu.css */
1200
1206
  .c-action-menu {
1201
1207
  display: flex;
1202
- height: 2rem;
1203
- width: 2rem;
1204
1208
  flex-shrink: 0;
1205
1209
  --tw-rotate: 0deg;
1206
1210
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
@@ -1212,7 +1216,6 @@ button {
1212
1216
  border-radius: 0.375rem;
1213
1217
  border-style: none;
1214
1218
  background-color: transparent;
1215
- padding: 0.25rem;
1216
1219
  outline-offset: -1px;
1217
1220
  transition-property:
1218
1221
  color,
@@ -1230,8 +1233,6 @@ button {
1230
1233
  transition-duration: 150ms;
1231
1234
  }
1232
1235
  .c-action-menu-dot {
1233
- height: 4px;
1234
- width: 4px;
1235
1236
  border-radius: 9999px;
1236
1237
  background-color: rgb(var(--c-color-gray));
1237
1238
  }
@@ -1261,15 +1262,33 @@ button {
1261
1262
  --tw-bg-opacity: 1;
1262
1263
  background-color: rgb(var(--c-color-purple-100-800) / var(--tw-bg-opacity));
1263
1264
  }
1265
+ .c-action-menu-xs {
1266
+ height: 1.5rem;
1267
+ width: 1.5rem;
1268
+ padding: 0.125rem;
1269
+ }
1270
+ .c-action-menu-xs .c-action-menu-dot {
1271
+ height: 0.125rem;
1272
+ width: 0.125rem;
1273
+ }
1274
+ .c-action-menu-sm {
1275
+ height: 2rem;
1276
+ width: 2rem;
1277
+ padding: 0.25rem;
1278
+ }
1279
+ .c-action-menu-sm .c-action-menu-dot {
1280
+ height: 0.25rem;
1281
+ width: 0.25rem;
1282
+ }
1264
1283
  .c-action-menu-item {
1265
1284
  display: flex;
1266
1285
  cursor: pointer;
1267
1286
  align-items: center;
1268
1287
  gap: 0.5rem;
1269
- padding-top: 0.625rem;
1270
- padding-bottom: 0.625rem;
1271
1288
  padding-left: 1.25rem;
1272
1289
  padding-right: 1.25rem;
1290
+ padding-top: 0.625rem;
1291
+ padding-bottom: 0.625rem;
1273
1292
  font-family:
1274
1293
  Roboto,
1275
1294
  ui-sans-serif,
@@ -1400,12 +1419,12 @@ button {
1400
1419
  outline-offset: 2px;
1401
1420
  }
1402
1421
  .c-dropdown-menu-item:first-child {
1403
- border-top-right-radius: 0.25rem;
1404
1422
  border-top-left-radius: 0.25rem;
1423
+ border-top-right-radius: 0.25rem;
1405
1424
  }
1406
1425
  .c-dropdown-menu-item:last-child {
1407
- border-bottom-right-radius: 0.25rem;
1408
1426
  border-bottom-left-radius: 0.25rem;
1427
+ border-bottom-right-radius: 0.25rem;
1409
1428
  }
1410
1429
 
1411
1430
  /* src/avatar/avatar.css */
@@ -3208,13 +3227,13 @@ button {
3208
3227
  will-change: transform;
3209
3228
  box-sizing: border-box;
3210
3229
  position: absolute;
3211
- top: 0px;
3212
3230
  left: 0px;
3231
+ top: 0px;
3213
3232
  z-index: 10;
3214
3233
  display: flex;
3215
3234
  border-radius: 0.375rem;
3216
3235
  --tw-bg-opacity: 1;
3217
- background-color: rgb(255 255 255 / var(--tw-bg-opacity));
3236
+ background-color: rgb(var(--c-color-elevate) / var(--tw-bg-opacity));
3218
3237
  padding: 0.25rem;
3219
3238
  opacity: 0;
3220
3239
  --tw-shadow: 0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1);
package/dist/index.d.ts CHANGED
@@ -19,11 +19,15 @@ type ItemProps = HTMLAttributes<HTMLLIElement> & {
19
19
  };
20
20
  declare function Item({ children, className, onSelect }: ItemProps): JSX.Element;
21
21
 
22
- type ActionMenuProps = {
22
+ type ButtonStylesProps$1 = VariantProps<typeof buttonStyles$2>;
23
+ declare const buttonStyles$2: (props?: ({
24
+ size?: "xs" | "sm" | null | undefined;
25
+ } & class_variance_authority_dist_types.ClassProp) | undefined) => string;
26
+ type ActionMenuProps = ButtonStylesProps$1 & {
23
27
  children: ReactNode;
24
28
  tabIndex?: number;
25
29
  };
26
- declare function ActionMenu({ children, tabIndex }: ActionMenuProps): JSX.Element;
30
+ declare function ActionMenu({ children, tabIndex, size }: ActionMenuProps): JSX.Element;
27
31
  declare namespace ActionMenu {
28
32
  var Item: typeof Item;
29
33
  var Separator: typeof Separator;
package/dist/index.js CHANGED
@@ -251,6 +251,9 @@ function Card({ children, className, variant, ...delegated }) {
251
251
  // src/card/index.ts
252
252
  var cardToken = "c-card";
253
253
 
254
+ // src/action-menu/action-menu.tsx
255
+ var import_class_variance_authority7 = require("class-variance-authority");
256
+
254
257
  // src/dropdown-menu/index.ts
255
258
  var import_react_dropdown_menu = require("@radix-ui/react-dropdown-menu");
256
259
 
@@ -282,7 +285,7 @@ var import_jsx_runtime6 = require("react/jsx-runtime");
282
285
  function DropdownMenuRoot({
283
286
  children,
284
287
  content,
285
- alignContent = "start",
288
+ alignContent = "center",
286
289
  disabled,
287
290
  onOpenChange,
288
291
  ...delegated
@@ -295,12 +298,14 @@ function DropdownMenuRoot({
295
298
  asChild: true,
296
299
  children
297
300
  }),
298
- /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuPrimitive3.Content, {
299
- align: alignContent,
300
- sideOffset: 5,
301
- className: "c-dropdown-menu-content",
302
- ...delegated,
303
- children: content
301
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuPrimitive3.Portal, {
302
+ children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(DropdownMenuPrimitive3.Content, {
303
+ align: alignContent,
304
+ sideOffset: 5,
305
+ className: "c-dropdown-menu-content",
306
+ ...delegated,
307
+ children: content
308
+ })
304
309
  })
305
310
  ]
306
311
  });
@@ -338,15 +343,27 @@ function Separator2({ className }) {
338
343
 
339
344
  // src/action-menu/action-menu.tsx
340
345
  var import_jsx_runtime9 = require("react/jsx-runtime");
341
- function ActionMenu({ children, tabIndex }) {
346
+ var buttonStyles2 = (0, import_class_variance_authority7.cva)("c-action-menu", {
347
+ variants: {
348
+ size: {
349
+ xs: "c-action-menu-xs",
350
+ sm: "c-action-menu-sm"
351
+ }
352
+ },
353
+ defaultVariants: {
354
+ size: "sm"
355
+ }
356
+ });
357
+ function ActionMenu({ children, tabIndex, size }) {
342
358
  return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(DropdownMenu.Root, {
343
359
  content: children,
344
360
  alignContent: "center",
345
361
  children: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)("button", {
362
+ "aria-label": "more options",
363
+ className: buttonStyles2({ size }),
364
+ "data-testid": "action-menu-button",
346
365
  tabIndex,
347
366
  type: "button",
348
- className: "c-action-menu",
349
- "aria-label": "more options",
350
367
  children: [
351
368
  /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("span", {
352
369
  className: "sr-only",
@@ -370,7 +387,7 @@ ActionMenu.Separator = Separator2;
370
387
 
371
388
  // src/avatar/avatar.tsx
372
389
  var import_react3 = require("react");
373
- var import_class_variance_authority7 = require("class-variance-authority");
390
+ var import_class_variance_authority8 = require("class-variance-authority");
374
391
 
375
392
  // src/avatar/get-initials.ts
376
393
  var getInitials = (name) => {
@@ -381,7 +398,7 @@ var getInitials = (name) => {
381
398
 
382
399
  // src/avatar/avatar.tsx
383
400
  var import_jsx_runtime10 = require("react/jsx-runtime");
384
- var avatarClassName = (0, import_class_variance_authority7.cva)(["c-avatar"], {
401
+ var avatarClassName = (0, import_class_variance_authority8.cva)(["c-avatar"], {
385
402
  variants: {
386
403
  size: {
387
404
  md: "c-avatar-md",
@@ -443,7 +460,7 @@ var destroyFns = [];
443
460
 
444
461
  // src/dialog/dialog.tsx
445
462
  var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
446
- var import_class_variance_authority8 = require("class-variance-authority");
463
+ var import_class_variance_authority9 = require("class-variance-authority");
447
464
 
448
465
  // src/iconography/add.tsx
449
466
  var import_react5 = require("react");
@@ -2972,7 +2989,7 @@ var IconMap = {
2972
2989
  info: Icon.Info,
2973
2990
  warning: Icon.Warning
2974
2991
  };
2975
- var dialogContentStyles = (0, import_class_variance_authority8.cva)("c-dialog", {
2992
+ var dialogContentStyles = (0, import_class_variance_authority9.cva)("c-dialog", {
2976
2993
  variants: {
2977
2994
  withIcon: {
2978
2995
  true: "c-dialog-with-icon"
@@ -3022,7 +3039,7 @@ function DialogContent({ children, closable = true, type, className, container,
3022
3039
  }
3023
3040
  function DialogTitle({ className, ...delegated }) {
3024
3041
  return /* @__PURE__ */ (0, import_jsx_runtime61.jsx)(DialogPrimitive.Title, {
3025
- className: (0, import_class_variance_authority8.cx)("c-dialog-title", className),
3042
+ className: (0, import_class_variance_authority9.cx)("c-dialog-title", className),
3026
3043
  ...delegated
3027
3044
  });
3028
3045
  }
@@ -3263,9 +3280,9 @@ function destroyAll() {
3263
3280
 
3264
3281
  // src/icon-button/icon-button.tsx
3265
3282
  var import_react54 = require("react");
3266
- var import_class_variance_authority9 = require("class-variance-authority");
3283
+ var import_class_variance_authority10 = require("class-variance-authority");
3267
3284
  var import_jsx_runtime64 = require("react/jsx-runtime");
3268
- var buttonStyles2 = (0, import_class_variance_authority9.cva)(["c-icon-button"], {
3285
+ var buttonStyles3 = (0, import_class_variance_authority10.cva)(["c-icon-button"], {
3269
3286
  variants: {
3270
3287
  variant: {
3271
3288
  default: "",
@@ -3289,7 +3306,7 @@ var IconButton = (0, import_react54.forwardRef)(
3289
3306
  return /* @__PURE__ */ (0, import_jsx_runtime64.jsx)("button", {
3290
3307
  ref,
3291
3308
  type,
3292
- className: buttonStyles2({ size, variant, className }),
3309
+ className: buttonStyles3({ size, variant, className }),
3293
3310
  ...delegated,
3294
3311
  children
3295
3312
  });
@@ -3299,9 +3316,9 @@ IconButton.displayName = "Button";
3299
3316
 
3300
3317
  // src/inline-radio/inline-radio.tsx
3301
3318
  var RadioGroupPrimitive = __toESM(require("@radix-ui/react-radio-group"));
3302
- var import_class_variance_authority10 = require("class-variance-authority");
3319
+ var import_class_variance_authority11 = require("class-variance-authority");
3303
3320
  var import_jsx_runtime65 = require("react/jsx-runtime");
3304
- var inlineRadioGroupStyles = (0, import_class_variance_authority10.cva)("c-inline-radio-group", {
3321
+ var inlineRadioGroupStyles = (0, import_class_variance_authority11.cva)("c-inline-radio-group", {
3305
3322
  variants: {
3306
3323
  size: {
3307
3324
  xs: "c-inline-radio-group-xs",
@@ -3323,7 +3340,7 @@ function InlineRadioGroup({ size, className, ...delegated }) {
3323
3340
  function InlineRadioItem({ children, className, ...delegated }) {
3324
3341
  return /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(RadioGroupPrimitive.Item, {
3325
3342
  ...delegated,
3326
- className: (0, import_class_variance_authority10.cx)("c-inline-radio", className),
3343
+ className: (0, import_class_variance_authority11.cx)("c-inline-radio", className),
3327
3344
  children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(RadioGroupPrimitive.Indicator, {
3328
3345
  forceMount: true,
3329
3346
  children
@@ -3337,13 +3354,13 @@ var InlineRadio = {
3337
3354
 
3338
3355
  // src/input-with-label/input-with-label.tsx
3339
3356
  var import_react58 = require("react");
3340
- var import_class_variance_authority13 = require("class-variance-authority");
3357
+ var import_class_variance_authority14 = require("class-variance-authority");
3341
3358
 
3342
3359
  // src/input/input.tsx
3343
- var import_class_variance_authority11 = require("class-variance-authority");
3360
+ var import_class_variance_authority12 = require("class-variance-authority");
3344
3361
  var import_react55 = require("react");
3345
3362
  var import_jsx_runtime66 = require("react/jsx-runtime");
3346
- var inputStyles = (0, import_class_variance_authority11.cva)(["c-input"], {
3363
+ var inputStyles = (0, import_class_variance_authority12.cva)(["c-input"], {
3347
3364
  variants: {},
3348
3365
  defaultVariants: {}
3349
3366
  });
@@ -3359,12 +3376,12 @@ Input.displayName = "Input";
3359
3376
 
3360
3377
  // src/label/label.tsx
3361
3378
  var import_react56 = require("react");
3362
- var import_class_variance_authority12 = require("class-variance-authority");
3379
+ var import_class_variance_authority13 = require("class-variance-authority");
3363
3380
  var import_jsx_runtime67 = require("react/jsx-runtime");
3364
3381
  var Label2 = (0, import_react56.forwardRef)(({ className, ...delegated }, ref) => {
3365
3382
  return /* @__PURE__ */ (0, import_jsx_runtime67.jsx)("label", {
3366
3383
  ref,
3367
- className: (0, import_class_variance_authority12.cx)("c-label", className),
3384
+ className: (0, import_class_variance_authority13.cx)("c-label", className),
3368
3385
  ...delegated
3369
3386
  });
3370
3387
  });
@@ -3393,7 +3410,7 @@ var Triangle = (0, import_react57.forwardRef)((delegated, ref) => {
3393
3410
 
3394
3411
  // src/input-with-label/input-with-label.tsx
3395
3412
  var import_jsx_runtime69 = require("react/jsx-runtime");
3396
- var inputWithLabelStyles = (0, import_class_variance_authority13.cva)(["c-input-with-label"], {
3413
+ var inputWithLabelStyles = (0, import_class_variance_authority14.cva)(["c-input-with-label"], {
3397
3414
  variants: {
3398
3415
  variant: {
3399
3416
  default: "",
@@ -3420,7 +3437,7 @@ var InputWithLabel = (0, import_react58.forwardRef)(
3420
3437
  className: "c-input-with-label-input-wrap",
3421
3438
  children: [
3422
3439
  /* @__PURE__ */ (0, import_jsx_runtime69.jsx)(Input, {
3423
- className: (0, import_class_variance_authority13.cx)("c-input-with-label-input", className),
3440
+ className: (0, import_class_variance_authority14.cx)("c-input-with-label-input", className),
3424
3441
  ref,
3425
3442
  id,
3426
3443
  ...delegated
@@ -3441,11 +3458,11 @@ InputWithLabel.displayName = "InputWithLabel";
3441
3458
 
3442
3459
  // src/progress/progress.tsx
3443
3460
  var ProgressPrimitives = __toESM(require("@radix-ui/react-progress"));
3444
- var import_class_variance_authority14 = require("class-variance-authority");
3461
+ var import_class_variance_authority15 = require("class-variance-authority");
3445
3462
  var import_jsx_runtime70 = require("react/jsx-runtime");
3446
3463
  function Progress({ className, value }) {
3447
3464
  return /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ProgressPrimitives.Root, {
3448
- className: (0, import_class_variance_authority14.cx)(className, "c-progress-root"),
3465
+ className: (0, import_class_variance_authority15.cx)(className, "c-progress-root"),
3449
3466
  value,
3450
3467
  children: /* @__PURE__ */ (0, import_jsx_runtime70.jsx)(ProgressPrimitives.Indicator, {
3451
3468
  className: "c-progress-indicator",
@@ -3494,9 +3511,9 @@ SelectItem.displayName = "SelectItem";
3494
3511
  // src/select/select-root.tsx
3495
3512
  var import_react60 = require("react");
3496
3513
  var SelectPrimitives2 = __toESM(require("@radix-ui/react-select"));
3497
- var import_class_variance_authority15 = require("class-variance-authority");
3514
+ var import_class_variance_authority16 = require("class-variance-authority");
3498
3515
  var import_jsx_runtime73 = require("react/jsx-runtime");
3499
- var selectTriggerStyles = (0, import_class_variance_authority15.cva)("c-select-trigger", {
3516
+ var selectTriggerStyles = (0, import_class_variance_authority16.cva)("c-select-trigger", {
3500
3517
  variants: {
3501
3518
  size: {
3502
3519
  xs: "c-select-trigger-xs",
@@ -3556,12 +3573,12 @@ var Select = {
3556
3573
 
3557
3574
  // src/slider/slider.tsx
3558
3575
  var SliderPrimitive = __toESM(require("@radix-ui/react-slider"));
3559
- var import_class_variance_authority16 = require("class-variance-authority");
3576
+ var import_class_variance_authority17 = require("class-variance-authority");
3560
3577
  var import_react61 = require("react");
3561
3578
  var import_jsx_runtime74 = require("react/jsx-runtime");
3562
3579
  var Slider = (0, import_react61.forwardRef)(({ className, transparentRange, ...delegated }, ref) => {
3563
3580
  return /* @__PURE__ */ (0, import_jsx_runtime74.jsxs)(SliderPrimitive.Root, {
3564
- className: (0, import_class_variance_authority16.cx)("c-slider-root", className),
3581
+ className: (0, import_class_variance_authority17.cx)("c-slider-root", className),
3565
3582
  ref,
3566
3583
  ...delegated,
3567
3584
  children: [
@@ -3579,9 +3596,9 @@ var Slider = (0, import_react61.forwardRef)(({ className, transparentRange, ...d
3579
3596
  });
3580
3597
 
3581
3598
  // src/tag/tag.tsx
3582
- var import_class_variance_authority17 = require("class-variance-authority");
3599
+ var import_class_variance_authority18 = require("class-variance-authority");
3583
3600
  var import_jsx_runtime75 = require("react/jsx-runtime");
3584
- var tagStyles = (0, import_class_variance_authority17.cva)("c-tag", {
3601
+ var tagStyles = (0, import_class_variance_authority18.cva)("c-tag", {
3585
3602
  variants: {
3586
3603
  variant: {
3587
3604
  default: "",
package/dist/index.mjs CHANGED
@@ -191,8 +191,11 @@ function Card({ children, className, variant, ...delegated }) {
191
191
  // src/card/index.ts
192
192
  var cardToken = "c-card";
193
193
 
194
+ // src/action-menu/action-menu.tsx
195
+ import { cva as cva3 } from "class-variance-authority";
196
+
194
197
  // src/dropdown-menu/index.ts
195
- import { Portal, Separator } from "@radix-ui/react-dropdown-menu";
198
+ import { Portal as Portal2, Separator } from "@radix-ui/react-dropdown-menu";
196
199
 
197
200
  // src/dropdown-menu/dropdown-menu-item.tsx
198
201
  import * as DropdownMenuPrimitive from "@radix-ui/react-dropdown-menu";
@@ -222,7 +225,7 @@ import { jsx as jsx6, jsxs as jsxs3 } from "react/jsx-runtime";
222
225
  function DropdownMenuRoot({
223
226
  children,
224
227
  content,
225
- alignContent = "start",
228
+ alignContent = "center",
226
229
  disabled,
227
230
  onOpenChange,
228
231
  ...delegated
@@ -235,12 +238,14 @@ function DropdownMenuRoot({
235
238
  asChild: true,
236
239
  children
237
240
  }),
238
- /* @__PURE__ */ jsx6(DropdownMenuPrimitive3.Content, {
239
- align: alignContent,
240
- sideOffset: 5,
241
- className: "c-dropdown-menu-content",
242
- ...delegated,
243
- children: content
241
+ /* @__PURE__ */ jsx6(DropdownMenuPrimitive3.Portal, {
242
+ children: /* @__PURE__ */ jsx6(DropdownMenuPrimitive3.Content, {
243
+ align: alignContent,
244
+ sideOffset: 5,
245
+ className: "c-dropdown-menu-content",
246
+ ...delegated,
247
+ children: content
248
+ })
244
249
  })
245
250
  ]
246
251
  });
@@ -252,7 +257,7 @@ var DropdownMenu = {
252
257
  Item: DropdownMenuItem,
253
258
  Label: DropdownMenuLabel,
254
259
  Separator,
255
- Portal
260
+ Portal: Portal2
256
261
  };
257
262
 
258
263
  // src/action-menu/action-item.tsx
@@ -278,15 +283,27 @@ function Separator2({ className }) {
278
283
 
279
284
  // src/action-menu/action-menu.tsx
280
285
  import { jsx as jsx9, jsxs as jsxs4 } from "react/jsx-runtime";
281
- function ActionMenu({ children, tabIndex }) {
286
+ var buttonStyles2 = cva3("c-action-menu", {
287
+ variants: {
288
+ size: {
289
+ xs: "c-action-menu-xs",
290
+ sm: "c-action-menu-sm"
291
+ }
292
+ },
293
+ defaultVariants: {
294
+ size: "sm"
295
+ }
296
+ });
297
+ function ActionMenu({ children, tabIndex, size }) {
282
298
  return /* @__PURE__ */ jsx9(DropdownMenu.Root, {
283
299
  content: children,
284
300
  alignContent: "center",
285
301
  children: /* @__PURE__ */ jsxs4("button", {
302
+ "aria-label": "more options",
303
+ className: buttonStyles2({ size }),
304
+ "data-testid": "action-menu-button",
286
305
  tabIndex,
287
306
  type: "button",
288
- className: "c-action-menu",
289
- "aria-label": "more options",
290
307
  children: [
291
308
  /* @__PURE__ */ jsx9("span", {
292
309
  className: "sr-only",
@@ -310,7 +327,7 @@ ActionMenu.Separator = Separator2;
310
327
 
311
328
  // src/avatar/avatar.tsx
312
329
  import { forwardRef as forwardRef3 } from "react";
313
- import { cva as cva3 } from "class-variance-authority";
330
+ import { cva as cva4 } from "class-variance-authority";
314
331
 
315
332
  // src/avatar/get-initials.ts
316
333
  var getInitials = (name) => {
@@ -321,7 +338,7 @@ var getInitials = (name) => {
321
338
 
322
339
  // src/avatar/avatar.tsx
323
340
  import { jsx as jsx10 } from "react/jsx-runtime";
324
- var avatarClassName = cva3(["c-avatar"], {
341
+ var avatarClassName = cva4(["c-avatar"], {
325
342
  variants: {
326
343
  size: {
327
344
  md: "c-avatar-md",
@@ -383,7 +400,7 @@ var destroyFns = [];
383
400
 
384
401
  // src/dialog/dialog.tsx
385
402
  import * as DialogPrimitive from "@radix-ui/react-dialog";
386
- import { cva as cva4, cx as cx5 } from "class-variance-authority";
403
+ import { cva as cva5, cx as cx5 } from "class-variance-authority";
387
404
 
388
405
  // src/iconography/add.tsx
389
406
  import { forwardRef as forwardRef5 } from "react";
@@ -2912,7 +2929,7 @@ var IconMap = {
2912
2929
  info: Icon.Info,
2913
2930
  warning: Icon.Warning
2914
2931
  };
2915
- var dialogContentStyles = cva4("c-dialog", {
2932
+ var dialogContentStyles = cva5("c-dialog", {
2916
2933
  variants: {
2917
2934
  withIcon: {
2918
2935
  true: "c-dialog-with-icon"
@@ -3203,9 +3220,9 @@ function destroyAll() {
3203
3220
 
3204
3221
  // src/icon-button/icon-button.tsx
3205
3222
  import { forwardRef as forwardRef54 } from "react";
3206
- import { cva as cva5 } from "class-variance-authority";
3223
+ import { cva as cva6 } from "class-variance-authority";
3207
3224
  import { jsx as jsx64 } from "react/jsx-runtime";
3208
- var buttonStyles2 = cva5(["c-icon-button"], {
3225
+ var buttonStyles3 = cva6(["c-icon-button"], {
3209
3226
  variants: {
3210
3227
  variant: {
3211
3228
  default: "",
@@ -3229,7 +3246,7 @@ var IconButton = forwardRef54(
3229
3246
  return /* @__PURE__ */ jsx64("button", {
3230
3247
  ref,
3231
3248
  type,
3232
- className: buttonStyles2({ size, variant, className }),
3249
+ className: buttonStyles3({ size, variant, className }),
3233
3250
  ...delegated,
3234
3251
  children
3235
3252
  });
@@ -3239,9 +3256,9 @@ IconButton.displayName = "Button";
3239
3256
 
3240
3257
  // src/inline-radio/inline-radio.tsx
3241
3258
  import * as RadioGroupPrimitive from "@radix-ui/react-radio-group";
3242
- import { cx as cx6, cva as cva6 } from "class-variance-authority";
3259
+ import { cx as cx6, cva as cva7 } from "class-variance-authority";
3243
3260
  import { jsx as jsx65 } from "react/jsx-runtime";
3244
- var inlineRadioGroupStyles = cva6("c-inline-radio-group", {
3261
+ var inlineRadioGroupStyles = cva7("c-inline-radio-group", {
3245
3262
  variants: {
3246
3263
  size: {
3247
3264
  xs: "c-inline-radio-group-xs",
@@ -3277,13 +3294,13 @@ var InlineRadio = {
3277
3294
 
3278
3295
  // src/input-with-label/input-with-label.tsx
3279
3296
  import { forwardRef as forwardRef58 } from "react";
3280
- import { cva as cva8, cx as cx8 } from "class-variance-authority";
3297
+ import { cva as cva9, cx as cx8 } from "class-variance-authority";
3281
3298
 
3282
3299
  // src/input/input.tsx
3283
- import { cva as cva7 } from "class-variance-authority";
3300
+ import { cva as cva8 } from "class-variance-authority";
3284
3301
  import { forwardRef as forwardRef55 } from "react";
3285
3302
  import { jsx as jsx66 } from "react/jsx-runtime";
3286
- var inputStyles = cva7(["c-input"], {
3303
+ var inputStyles = cva8(["c-input"], {
3287
3304
  variants: {},
3288
3305
  defaultVariants: {}
3289
3306
  });
@@ -3333,7 +3350,7 @@ var Triangle = forwardRef57((delegated, ref) => {
3333
3350
 
3334
3351
  // src/input-with-label/input-with-label.tsx
3335
3352
  import { Fragment, jsx as jsx69, jsxs as jsxs54 } from "react/jsx-runtime";
3336
- var inputWithLabelStyles = cva8(["c-input-with-label"], {
3353
+ var inputWithLabelStyles = cva9(["c-input-with-label"], {
3337
3354
  variants: {
3338
3355
  variant: {
3339
3356
  default: "",
@@ -3434,9 +3451,9 @@ SelectItem.displayName = "SelectItem";
3434
3451
  // src/select/select-root.tsx
3435
3452
  import { forwardRef as forwardRef60 } from "react";
3436
3453
  import * as SelectPrimitives2 from "@radix-ui/react-select";
3437
- import { cva as cva9 } from "class-variance-authority";
3454
+ import { cva as cva10 } from "class-variance-authority";
3438
3455
  import { jsx as jsx73, jsxs as jsxs56 } from "react/jsx-runtime";
3439
- var selectTriggerStyles = cva9("c-select-trigger", {
3456
+ var selectTriggerStyles = cva10("c-select-trigger", {
3440
3457
  variants: {
3441
3458
  size: {
3442
3459
  xs: "c-select-trigger-xs",
@@ -3519,9 +3536,9 @@ var Slider = forwardRef61(({ className, transparentRange, ...delegated }, ref) =
3519
3536
  });
3520
3537
 
3521
3538
  // src/tag/tag.tsx
3522
- import { cva as cva10 } from "class-variance-authority";
3539
+ import { cva as cva11 } from "class-variance-authority";
3523
3540
  import { jsx as jsx75 } from "react/jsx-runtime";
3524
- var tagStyles = cva10("c-tag", {
3541
+ var tagStyles = cva11("c-tag", {
3525
3542
  variants: {
3526
3543
  variant: {
3527
3544
  default: "",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crystallize/design-system",
3
- "version": "1.11.2",
3
+ "version": "1.11.4",
4
4
  "types": "./dist/index.d.ts",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -40,6 +40,7 @@
40
40
  "@radix-ui/react-checkbox": "1.0.1",
41
41
  "@radix-ui/react-dialog": "1.0.2",
42
42
  "@radix-ui/react-dropdown-menu": "2.0.1",
43
+ "@radix-ui/react-popover": "1.0.0",
43
44
  "@radix-ui/react-progress": "^1.0.1",
44
45
  "@radix-ui/react-radio-group": "1.1.0",
45
46
  "@radix-ui/react-select": "1.1.2",
@@ -88,8 +89,8 @@
88
89
  "tailwindcss": "^3.3.0",
89
90
  "tsup": "^6.5.0",
90
91
  "typescript": "^4.9.4",
91
- "vite": "^4.1.1",
92
- "vitest": "^0.29.1",
92
+ "vite": "^4.2.1",
93
+ "vitest": "^0.30.1",
93
94
  "tsconfig": "0.0.0"
94
95
  },
95
96
  "keywords": [
@@ -23,3 +23,15 @@ export const Default: Story = {
23
23
  </ActionMenu>
24
24
  ),
25
25
  };
26
+
27
+ export const XS: Story = {
28
+ args: {},
29
+ render: () => (
30
+ <ActionMenu size="xs">
31
+ <ActionMenu.Item onSelect={() => console.warn('Download')}>Download</ActionMenu.Item>
32
+ <ActionMenu.Item className="danger" onSelect={() => console.warn('Delete')}>
33
+ Delete
34
+ </ActionMenu.Item>
35
+ </ActionMenu>
36
+ ),
37
+ };
@@ -1,12 +1,15 @@
1
1
  .c-action-menu {
2
- @apply flex h-8 w-8 shrink-0 rotate-0 cursor-pointer flex-col items-center justify-center gap-[2px] rounded-md border-none bg-transparent p-1 -outline-offset-1 transition;
2
+ @apply flex shrink-0 rotate-0 cursor-pointer flex-col items-center justify-center gap-[2px] rounded-md border-none bg-transparent -outline-offset-1 transition;
3
+
3
4
  &-dot {
4
- @apply h-[4px] w-[4px] rounded-full bg-gray;
5
+ @apply rounded-full bg-gray;
5
6
  }
7
+
6
8
  &[data-state='open'],
7
9
  [aria-expanded='true'] {
8
10
  @apply flex-row gap-[3px];
9
11
  }
12
+
10
13
  &:focus-visible {
11
14
  @apply outline outline-1 outline-inherit;
12
15
  outline-color: currentColor;
@@ -21,8 +24,24 @@
21
24
  }
22
25
  }
23
26
 
27
+ .c-action-menu-xs {
28
+ @apply h-6 w-6 p-0.5;
29
+
30
+ .c-action-menu-dot {
31
+ @apply h-0.5 w-0.5;
32
+ }
33
+ }
34
+
35
+ .c-action-menu-sm {
36
+ @apply h-8 w-8 p-1;
37
+
38
+ .c-action-menu-dot {
39
+ @apply h-1 w-1;
40
+ }
41
+ }
42
+
24
43
  .c-action-menu-item {
25
- @apply flex cursor-pointer items-center gap-2 py-2.5 px-5 font-sans text-sm font-medium text-gray;
44
+ @apply flex cursor-pointer items-center gap-2 px-5 py-2.5 font-sans text-sm font-medium text-gray;
26
45
 
27
46
  &:hover {
28
47
  @apply bg-gray-50-900;
@@ -0,0 +1,53 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+
4
+ import { ActionMenu } from './index';
5
+
6
+ describe('ActionMenu', () => {
7
+ it('renders correctly', () => {
8
+ render(
9
+ <ActionMenu>
10
+ <ActionMenu.Item onSelect={() => {}}>Delete</ActionMenu.Item>
11
+ </ActionMenu>,
12
+ );
13
+
14
+ expect(screen.getByLabelText(/more options/i)).toBeInTheDocument();
15
+ });
16
+
17
+ it('opens the menu and selects an option when clicking on an action item', async () => {
18
+ const onSelectOption = vi.fn();
19
+ const callbackThatShouldNotBeExecuted = vi.fn();
20
+ const user = userEvent.setup();
21
+
22
+ const touchableProps = { onSelect: onSelectOption, onClick: onSelectOption };
23
+ const touchablePropsThatShouldNotBeCalled = {
24
+ onSelect: callbackThatShouldNotBeExecuted,
25
+ onClick: callbackThatShouldNotBeExecuted,
26
+ };
27
+
28
+ render(
29
+ <ActionMenu>
30
+ <ActionMenu.Item {...touchableProps}>Add</ActionMenu.Item>
31
+ <ActionMenu.Item {...touchablePropsThatShouldNotBeCalled}>Delete</ActionMenu.Item>
32
+ </ActionMenu>,
33
+ );
34
+
35
+ const triggerButton = screen.getByTestId('action-menu-button') as HTMLButtonElement;
36
+ await user.click(triggerButton);
37
+
38
+ // The user should be able to see the dropdown menu
39
+ const dropdownMenu = await screen.getByRole('menu');
40
+ expect(dropdownMenu).toBeInTheDocument();
41
+
42
+ // The user should be able to see the list of options
43
+ const addOption = screen.getByText(/add/i);
44
+ expect(addOption).toBeInTheDocument();
45
+
46
+ // The user can interact with any of the options
47
+ await user.click(addOption);
48
+
49
+ // The following expect is failing
50
+ expect(onSelectOption).toBeCalledTimes(1);
51
+ expect(callbackThatShouldNotBeExecuted).toBeCalledTimes(0);
52
+ });
53
+ });
@@ -1,18 +1,38 @@
1
1
  import type { ReactNode } from 'react';
2
+ import { VariantProps, cva } from 'class-variance-authority';
2
3
 
3
4
  import { DropdownMenu } from '../dropdown-menu';
4
5
  import { Item } from './action-item';
5
6
  import { Separator } from './action-item-separator';
6
7
 
7
- type ActionMenuProps = {
8
+ type ButtonStylesProps = VariantProps<typeof buttonStyles>;
9
+ const buttonStyles = cva('c-action-menu', {
10
+ variants: {
11
+ size: {
12
+ xs: 'c-action-menu-xs',
13
+ sm: 'c-action-menu-sm',
14
+ },
15
+ },
16
+ defaultVariants: {
17
+ size: 'sm',
18
+ },
19
+ });
20
+
21
+ type ActionMenuProps = ButtonStylesProps & {
8
22
  children: ReactNode;
9
23
  tabIndex?: number;
10
24
  };
11
25
 
12
- export function ActionMenu({ children, tabIndex }: ActionMenuProps) {
26
+ export function ActionMenu({ children, tabIndex, size }: ActionMenuProps) {
13
27
  return (
14
28
  <DropdownMenu.Root content={children} alignContent="center">
15
- <button tabIndex={tabIndex} type="button" className="c-action-menu" aria-label="more options">
29
+ <button
30
+ aria-label="more options"
31
+ className={buttonStyles({ size })}
32
+ data-testid="action-menu-button"
33
+ tabIndex={tabIndex}
34
+ type="button"
35
+ >
16
36
  <span className="sr-only">Open more options</span>
17
37
  <span className="c-action-menu-dot"></span>
18
38
  <span className="c-action-menu-dot"></span>
@@ -0,0 +1,22 @@
1
+ import { render, screen } from '@testing-library/react';
2
+ import userEvent from '@testing-library/user-event';
3
+
4
+ import { Button } from './index';
5
+
6
+ describe('Button', () => {
7
+ it('renders correctly', () => {
8
+ render(<Button>Hey</Button>);
9
+
10
+ expect(screen.getByText(/Hey/i)).toBeInTheDocument();
11
+ });
12
+
13
+ it('fires the onClick event', async () => {
14
+ const onClick = vi.fn();
15
+
16
+ render(<Button onClick={onClick}>Hey</Button>);
17
+
18
+ await userEvent.click(screen.getByRole('button'));
19
+
20
+ expect(onClick).toBeCalledTimes(1);
21
+ });
22
+ });
@@ -1,7 +1,7 @@
1
1
  import type { ReactNode } from 'react';
2
2
  import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
3
3
 
4
- type DropdownMenuRootProps = DropdownMenuPrimitive.MenuContentProps & {
4
+ export type DropdownMenuRootProps = DropdownMenuPrimitive.MenuContentProps & {
5
5
  children: ReactNode;
6
6
  content: ReactNode;
7
7
  alignContent?: 'start' | 'center' | 'end';
@@ -12,7 +12,7 @@ type DropdownMenuRootProps = DropdownMenuPrimitive.MenuContentProps & {
12
12
  export function DropdownMenuRoot({
13
13
  children,
14
14
  content,
15
- alignContent = 'start',
15
+ alignContent = 'center',
16
16
  disabled,
17
17
  onOpenChange,
18
18
  ...delegated
@@ -22,14 +22,16 @@ export function DropdownMenuRoot({
22
22
  <DropdownMenuPrimitive.Trigger disabled={disabled} asChild>
23
23
  {children}
24
24
  </DropdownMenuPrimitive.Trigger>
25
- <DropdownMenuPrimitive.Content
26
- align={alignContent}
27
- sideOffset={5}
28
- className="c-dropdown-menu-content"
29
- {...delegated}
30
- >
31
- {content}
32
- </DropdownMenuPrimitive.Content>
25
+ <DropdownMenuPrimitive.Portal>
26
+ <DropdownMenuPrimitive.Content
27
+ align={alignContent}
28
+ sideOffset={5}
29
+ className="c-dropdown-menu-content"
30
+ {...delegated}
31
+ >
32
+ {content}
33
+ </DropdownMenuPrimitive.Content>
34
+ </DropdownMenuPrimitive.Portal>
33
35
  </DropdownMenuPrimitive.Root>
34
36
  );
35
37
  }
@@ -16,5 +16,5 @@
16
16
  @apply bg-gray-50-900 outline-none;
17
17
  }
18
18
 
19
- @apply first:rounded-tr first:rounded-tl last:rounded-br last:rounded-bl;
19
+ @apply first:rounded-tl first:rounded-tr last:rounded-bl last:rounded-br;
20
20
  }
@@ -0,0 +1 @@
1
+ export * from './popover';
@@ -0,0 +1,18 @@
1
+ import type { ReactNode } from 'react';
2
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
3
+
4
+ import { Icon } from '../iconography';
5
+
6
+ export type PopoverCloseProps = PopoverPrimitive.PopoverCloseProps & {
7
+ children?: ReactNode;
8
+ };
9
+
10
+ export function PopoverClose(props: PopoverCloseProps) {
11
+ const { asChild, children } = props;
12
+
13
+ return (
14
+ <PopoverPrimitive.Close asChild={asChild} className="c-popover-close">
15
+ {children ?? <Icon.Cancel width={16} height={16} />}
16
+ </PopoverPrimitive.Close>
17
+ );
18
+ }
@@ -0,0 +1,11 @@
1
+ .c-popover-content {
2
+ @apply rounded bg-elevate text-xs text-gray-700-200 shadow focus-visible:outline-none;
3
+ }
4
+
5
+ .c-popover-close {
6
+ @apply absolute right-1 top-1 flex cursor-pointer items-center justify-center rounded-full border-0 bg-transparent p-1;
7
+ }
8
+
9
+ .c-popover-arrow {
10
+ @apply fill-white;
11
+ }
@@ -0,0 +1,48 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+
3
+ import { Popover } from '.';
4
+ import { Icon } from '../iconography';
5
+
6
+ const meta: Meta<typeof Popover> = {
7
+ title: 'Components/Popover',
8
+ component: Popover,
9
+ argTypes: {
10
+ side: {
11
+ options: ['top', 'right', 'bottom', 'left'],
12
+ control: {
13
+ type: 'select',
14
+ },
15
+ },
16
+ align: {
17
+ options: ['start', 'center', 'end'],
18
+ control: {
19
+ type: 'select',
20
+ },
21
+ },
22
+ },
23
+ };
24
+
25
+ export default meta;
26
+ type Story = StoryObj<typeof Popover>;
27
+
28
+ export const SimpleTemplate: Story = {
29
+ name: 'Simple Template',
30
+ render: args => (
31
+ <div className="flex w-1/2 justify-center pt-14">
32
+ <Popover {...args} content="Content goes here">
33
+ <Icon.Customers width={32} height={32} />
34
+ </Popover>
35
+ </div>
36
+ ),
37
+ };
38
+
39
+ export const WithCustomCloseButton: Story = {
40
+ name: 'With custom Close button',
41
+ render: () => (
42
+ <div className="flex w-1/2 justify-center pt-14">
43
+ <Popover content="Content goes here" side="left" closeButton={<button>close</button>}>
44
+ <Icon.Customers width={32} height={32} />
45
+ </Popover>
46
+ </div>
47
+ ),
48
+ };
@@ -0,0 +1,45 @@
1
+ import type { ReactNode } from 'react';
2
+ import { cx } from 'class-variance-authority';
3
+ import * as PopoverPrimitive from '@radix-ui/react-popover';
4
+
5
+ import './popover.css';
6
+ import { PopoverClose } from './popover-close';
7
+
8
+ type PopoverProps = Pick<PopoverPrimitive.PopoverProps, 'open' | 'onOpenChange'> &
9
+ Pick<PopoverPrimitive.PortalProps, 'container'> &
10
+ PopoverPrimitive.PopperContentProps & {
11
+ children: ReactNode;
12
+ closeButton?: boolean | JSX.Element;
13
+ hasArrow?: boolean;
14
+ content: ReactNode;
15
+ };
16
+
17
+ export function Popover({
18
+ children,
19
+ closeButton,
20
+ content,
21
+ side,
22
+ open,
23
+ onOpenChange,
24
+ className,
25
+ container,
26
+ hasArrow = true,
27
+ ...delegatedContent
28
+ }: PopoverProps) {
29
+ return (
30
+ <PopoverPrimitive.Root open={open} onOpenChange={onOpenChange}>
31
+ <PopoverPrimitive.Trigger asChild>{children}</PopoverPrimitive.Trigger>
32
+ <PopoverPrimitive.Portal container={container}>
33
+ <PopoverPrimitive.Content {...delegatedContent} side={side} className={cx('c-popover-content', className)}>
34
+ {!closeButton ? null : (
35
+ <PopoverClose asChild={typeof closeButton !== 'boolean'}>
36
+ {typeof closeButton !== 'boolean' ? closeButton : null}
37
+ </PopoverClose>
38
+ )}
39
+ {hasArrow && <PopoverPrimitive.Arrow className="c-popover-arrow" offset={5} />}
40
+ {content}
41
+ </PopoverPrimitive.Content>
42
+ </PopoverPrimitive.Portal>
43
+ </PopoverPrimitive.Root>
44
+ );
45
+ }
@@ -5,7 +5,7 @@
5
5
  height: 43px;
6
6
  will-change: transform;
7
7
  box-sizing: border-box;
8
- @apply absolute top-0 left-0 z-10 flex rounded-md bg-white p-1 opacity-0 shadow-md;
8
+ @apply absolute left-0 top-0 z-10 flex rounded-md bg-elevate p-1 opacity-0 shadow-md;
9
9
  }
10
10
 
11
11
  .c-floating-text-format-popup button.popup-item {
@@ -14,7 +14,7 @@ const meta: Meta<typeof RichTextEditor> = {
14
14
  decorators: [
15
15
  Story => (
16
16
  <div className="bg-gray-50-900 p-10">
17
- <div className="shadow-md border-red bg-white max-w-[1100px] mx-auto rounded-md">
17
+ <div className="shadow-md border-red bg-elevate max-w-[1100px] mx-auto rounded-md">
18
18
  <Story />
19
19
  </div>
20
20
  </div>