@crisp-ui-kit/crisp 0.54.2 → 0.54.3

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 (74) hide show
  1. package/dist/chip.css +7 -1
  2. package/dist/chip.d.ts +2 -1
  3. package/dist/chip.layered.css +7 -1
  4. package/dist/cjs/components/chip/chip.js +3 -2
  5. package/dist/cjs/components/chip/chip.recipe.js +37 -1
  6. package/dist/cjs/components/datatable/datatable.js +489 -111
  7. package/dist/cjs/components/emptystate/emptystate.js +3 -2
  8. package/dist/cjs/components/emptystate/emptystate.recipe.js +26 -1
  9. package/dist/cjs/components/personchip/index.js +17 -0
  10. package/dist/cjs/components/personchip/personchip.js +50 -0
  11. package/dist/cjs/components/table/table.js +2 -2
  12. package/dist/cjs/components/tabs/tabs.js +2 -2
  13. package/dist/cjs/components/tabs/tabs.recipe.js +30 -3
  14. package/dist/cjs/components/text/index.js +7 -0
  15. package/dist/cjs/components/text/text.js +55 -0
  16. package/dist/cjs/components/text/text.recipe.js +34 -0
  17. package/dist/cjs/index.js +2 -0
  18. package/dist/cjs/product/headerbar/headerbar.recipe.js +9 -1
  19. package/dist/cjs/product/recordpage/recordpage.recipe.js +10 -1
  20. package/dist/cjs/product/recordstable/recordstable.js +89 -6
  21. package/dist/cjs/product/richtext/richtext.recipe.js +26 -1
  22. package/dist/emptystate.css +15 -1
  23. package/dist/emptystate.d.ts +2 -2
  24. package/dist/emptystate.layered.css +15 -1
  25. package/dist/esm/components/chip/chip.js +3 -2
  26. package/dist/esm/components/chip/chip.recipe.js +37 -1
  27. package/dist/esm/components/datatable/datatable.js +488 -111
  28. package/dist/esm/components/emptystate/emptystate.js +4 -3
  29. package/dist/esm/components/emptystate/emptystate.recipe.js +26 -1
  30. package/dist/esm/components/emptystate/index.js +1 -1
  31. package/dist/esm/components/personchip/index.js +1 -0
  32. package/dist/esm/components/personchip/personchip.js +47 -0
  33. package/dist/esm/components/table/table.js +2 -2
  34. package/dist/esm/components/tabs/tabs.js +2 -2
  35. package/dist/esm/components/tabs/tabs.recipe.js +30 -3
  36. package/dist/esm/components/text/index.js +2 -0
  37. package/dist/esm/components/text/text.js +19 -0
  38. package/dist/esm/components/text/text.recipe.js +31 -0
  39. package/dist/esm/index.js +2 -0
  40. package/dist/esm/product/headerbar/headerbar.recipe.js +9 -1
  41. package/dist/esm/product/recordpage/recordpage.recipe.js +10 -1
  42. package/dist/esm/product/recordstable/recordstable.js +90 -8
  43. package/dist/esm/product/richtext/richtext.recipe.js +26 -1
  44. package/dist/headerbar.css +1 -1
  45. package/dist/headerbar.layered.css +1 -1
  46. package/dist/recordpage.css +13 -2
  47. package/dist/recordpage.layered.css +13 -2
  48. package/dist/richtext.css +11 -1
  49. package/dist/richtext.layered.css +11 -1
  50. package/dist/styles.css +64 -7
  51. package/dist/styles.layered.css +64 -7
  52. package/dist/tabs.css +7 -1
  53. package/dist/tabs.d.ts +2 -2
  54. package/dist/tabs.layered.css +7 -1
  55. package/dist/text.css +9 -0
  56. package/dist/text.d.ts +7 -0
  57. package/dist/text.layered.css +11 -0
  58. package/dist/types/components/chip/chip.d.ts +32 -0
  59. package/dist/types/components/chip/chip.recipe.d.ts +31 -0
  60. package/dist/types/components/datatable/datatable.d.ts +28 -4
  61. package/dist/types/components/emptystate/emptystate.d.ts +29 -4
  62. package/dist/types/components/emptystate/emptystate.recipe.d.ts +2 -0
  63. package/dist/types/components/emptystate/index.d.ts +1 -1
  64. package/dist/types/components/personchip/index.d.ts +1 -0
  65. package/dist/types/components/personchip/personchip.d.ts +37 -0
  66. package/dist/types/components/table/table.d.ts +36 -0
  67. package/dist/types/components/tabs/tabs.d.ts +4 -2
  68. package/dist/types/components/tabs/tabs.recipe.d.ts +18 -3
  69. package/dist/types/components/text/index.d.ts +2 -0
  70. package/dist/types/components/text/text.d.ts +32 -0
  71. package/dist/types/components/text/text.recipe.d.ts +40 -0
  72. package/dist/types/index.d.ts +2 -0
  73. package/dist/types/product/recordstable/recordstable.d.ts +24 -2
  74. package/package.json +11 -1
@@ -3,7 +3,16 @@
3
3
  & .crisp-emptystate-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; margin-bottom: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: color-mix(in srgb, var(--crisp-fg-primary) 5%, transparent); color: var(--crisp-fg-muted); }
4
4
  & .crisp-emptystate-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
5
5
  & .crisp-emptystate-desc { max-width: 320px; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
6
- & .crisp-emptystate-action { margin-top: var(--crisp-space-2); }
6
+ /* #603: measured 8px gap between "Import CSV"/"Connect data source" -- inline-flex so one action (the common case) or several lay out the same way, wrapping if the container is narrow. */
7
+ & .crisp-emptystate-action { display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: center; gap: var(--crisp-space-2); margin-top: var(--crisp-space-2); }
8
+ /* #603: Attio's zero-records "Learn more" card -- a label above a
9
+ clickable icon+title tile. Left/start-aligned, unlike the rest of
10
+ this centred panel, so it overrides the base text-align. */
11
+ & .crisp-emptystate-learnmore { display: flex; flex-direction: column; align-items: stretch; gap: var(--crisp-space-2); margin-top: var(--crisp-space-6); text-align: start; }
12
+ & .crisp-emptystate-learnmore-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
13
+ & .crisp-emptystate-learnmore-card { display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3) var(--crisp-space-2) var(--crisp-space-2); margin: 0; border: 1px solid var(--crisp-border-subtle); border-radius: 18px; background: var(--crisp-bg-surface); font: inherit; text-align: start; text-decoration: none; color: inherit; cursor: pointer; }
14
+ & .crisp-emptystate-learnmore-icon { display: inline-flex; align-items: center; justify-content: center; width: 56px; height: 56px; flex-shrink: 0; border-radius: var(--crisp-radius-xl); background: color-mix(in srgb, var(--crisp-fg-primary) 2%, transparent); color: var(--crisp-fg-muted); }
15
+ & .crisp-emptystate-learnmore-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
7
16
  }
8
17
  .crisp-emptystate--variant_default {
9
18
 
@@ -18,3 +27,8 @@
18
27
  & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
19
28
  & .crisp-emptystate-action { margin-top: var(--crisp-space-2); }
20
29
  }
30
+ .crisp-emptystate--variant_records {
31
+ & .crisp-emptystate-icon { width: 138px; height: 138px; margin-bottom: var(--crisp-space-2); border-radius: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 22%, transparent); background: radial-gradient(circle, color-mix(in srgb, var(--crisp-fg-primary) 12%, transparent) 1.2px, transparent 1.2px) 0 0 / 16px 16px; }
32
+ & .crisp-emptystate-title { font-size: 20px; line-height: 24px; }
33
+ & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
34
+ }
@@ -1,7 +1,7 @@
1
1
  import type { RecipeFn } from "../core/types";
2
2
 
3
3
  export interface EmptystateVariants {
4
- variant?: "default" | "illustrated" | "page";
4
+ variant?: "default" | "illustrated" | "page" | "records";
5
5
  }
6
6
 
7
- export declare const emptystateRecipe: RecipeFn<{ variant: { default: string; illustrated: string; page: string } }>;
7
+ export declare const emptystateRecipe: RecipeFn<{ variant: { default: string; illustrated: string; page: string; records: string } }>;
@@ -4,7 +4,16 @@
4
4
  & .crisp-emptystate-icon { display: inline-flex; align-items: center; justify-content: center; width: 40px; height: 40px; margin-bottom: var(--crisp-space-1); border-radius: var(--crisp-radius-xl); background: color-mix(in srgb, var(--crisp-fg-primary) 5%, transparent); color: var(--crisp-fg-muted); }
5
5
  & .crisp-emptystate-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-semibold); color: var(--crisp-fg-primary); }
6
6
  & .crisp-emptystate-desc { max-width: 320px; font-size: var(--crisp-text-md); color: var(--crisp-fg-muted); }
7
- & .crisp-emptystate-action { margin-top: var(--crisp-space-2); }
7
+ /* #603: measured 8px gap between "Import CSV"/"Connect data source" -- inline-flex so one action (the common case) or several lay out the same way, wrapping if the container is narrow. */
8
+ & .crisp-emptystate-action { display: inline-flex; align-items: center; flex-wrap: wrap; justify-content: center; gap: var(--crisp-space-2); margin-top: var(--crisp-space-2); }
9
+ /* #603: Attio's zero-records "Learn more" card -- a label above a
10
+ clickable icon+title tile. Left/start-aligned, unlike the rest of
11
+ this centred panel, so it overrides the base text-align. */
12
+ & .crisp-emptystate-learnmore { display: flex; flex-direction: column; align-items: stretch; gap: var(--crisp-space-2); margin-top: var(--crisp-space-6); text-align: start; }
13
+ & .crisp-emptystate-learnmore-label { font-size: var(--crisp-text-sm); font-weight: var(--crisp-weight-medium); color: color-mix(in srgb, var(--crisp-fg-primary) 50%, transparent); }
14
+ & .crisp-emptystate-learnmore-card { display: flex; align-items: center; gap: var(--crisp-space-2); padding: var(--crisp-space-2) var(--crisp-space-3) var(--crisp-space-2) var(--crisp-space-2); margin: 0; border: 1px solid var(--crisp-border-subtle); border-radius: 18px; background: var(--crisp-bg-surface); font: inherit; text-align: start; text-decoration: none; color: inherit; cursor: pointer; }
15
+ & .crisp-emptystate-learnmore-icon { display: inline-flex; align-items: center; justify-content: center; width: 56px; height: 56px; flex-shrink: 0; border-radius: var(--crisp-radius-xl); background: color-mix(in srgb, var(--crisp-fg-primary) 2%, transparent); color: var(--crisp-fg-muted); }
16
+ & .crisp-emptystate-learnmore-title { font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); color: var(--crisp-fg-primary); }
8
17
  }
9
18
  .crisp-emptystate--variant_default {
10
19
 
@@ -19,4 +28,9 @@
19
28
  & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
20
29
  & .crisp-emptystate-action { margin-top: var(--crisp-space-2); }
21
30
  }
31
+ .crisp-emptystate--variant_records {
32
+ & .crisp-emptystate-icon { width: 138px; height: 138px; margin-bottom: var(--crisp-space-2); border-radius: 0; color: color-mix(in srgb, var(--crisp-fg-primary) 22%, transparent); background: radial-gradient(circle, color-mix(in srgb, var(--crisp-fg-primary) 12%, transparent) 1.2px, transparent 1.2px) 0 0 / 16px 16px; }
33
+ & .crisp-emptystate-title { font-size: 20px; line-height: 24px; }
34
+ & .crisp-emptystate-desc { max-width: 266px; font-size: var(--crisp-text-lg); font-weight: var(--crisp-weight-medium); line-height: 20px; }
35
+ }
22
36
  }
@@ -16,7 +16,8 @@ import { chipRecipe } from "./chip.recipe.js";
16
16
  * that surface can be measured; don't guess the icon, its hit target, or its
17
17
  * spacing from the label.
18
18
  */
19
- export const Chip = React.forwardRef(({ tone, className, asChild, children, ...props }, ref) => {
20
- return (_jsx(Primitive.span, { ref: ref, asChild: asChild, className: chipRecipe({ tone, className }), ...props, children: children }));
19
+ export const Chip = React.forwardRef(({ tone, truncate, className, asChild, children, ...props }, ref) => {
20
+ const content = truncate && !asChild && typeof children === "string" ? (_jsx("span", { className: "crisp-chip-label", children: children })) : (children);
21
+ return (_jsx(Primitive.span, { ref: ref, asChild: asChild, className: chipRecipe({ tone, truncate, className }), ...props, children: content }));
21
22
  });
22
23
  Chip.displayName = "Chip";
@@ -17,7 +17,16 @@ const spec = defineSpec({
17
17
  base: {
18
18
  display: "inline-flex",
19
19
  alignItems: "center",
20
+ // Measured on Attio's own multi-child chip (Tasks page, "Assigned to"
21
+ // column: a 16px avatar + name in a neutral chip) -- the 3px gap between
22
+ // them. A single plain-text child (the only case before PersonChip) is
23
+ // unaffected, since `gap` does nothing with one flex child.
24
+ gap: "3px",
20
25
  height: c.size.chip,
26
+ // Lets the chip shrink below its content width inside a flex/grid cell
27
+ // -- `inline-flex` items don't by default -- which `truncate` below
28
+ // depends on and any consumer constraining a Chip's width already needs.
29
+ minWidth: 0,
21
30
  paddingInline: c.space["1"],
22
31
  borderRadius: c.radius.chip,
23
32
  fontSize: c.text.lg,
@@ -26,6 +35,33 @@ const spec = defineSpec({
26
35
  whiteSpace: "nowrap",
27
36
  },
28
37
  variants: {
38
+ truncate: {
39
+ // Ellipsis + `min-width: 0`, the same convention crisp's own
40
+ // `.crisp-datatable-entity-name`/`.crisp-datatable-th-label` already
41
+ // use for cramped text -- there is no single-overflowing-chip pattern
42
+ // to measure from Attio itself (its multi-value fields show a "+N"
43
+ // badge instead of truncating one chip's own text: Categories,
44
+ // Companies). Targets `.crisp-chip-label`, the inner span `Chip`
45
+ // wraps its string children in when `truncate` is set, not the root
46
+ // -- the root stays a flex row so a leading icon/avatar never shrinks
47
+ // alongside the text.
48
+ true: {
49
+ decls: {},
50
+ parts: [
51
+ {
52
+ selector: "& .crisp-chip-label",
53
+ decls: {
54
+ minWidth: 0,
55
+ overflow: "hidden",
56
+ textOverflow: "ellipsis",
57
+ whiteSpace: "nowrap",
58
+ display: "block",
59
+ },
60
+ },
61
+ ],
62
+ },
63
+ false: {},
64
+ },
29
65
  tone: {
30
66
  neutral: {
31
67
  background: soft(c.fgPrimary, 6),
@@ -69,7 +105,7 @@ const spec = defineSpec({
69
105
  },
70
106
  },
71
107
  },
72
- defaultVariants: { tone: "neutral" },
108
+ defaultVariants: { tone: "neutral", truncate: false },
73
109
  });
74
110
  const config = specToRecipe(spec);
75
111
  export const chipRecipe = Object.assign(resolveRecipe(config), { config });