@crisp-ui-kit/crisp 0.56.0 → 0.57.1
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/dist/accentpicker.css +5 -0
- package/dist/accentpicker.d.ts +7 -0
- package/dist/accentpicker.layered.css +7 -0
- package/dist/avatar.css +1 -1
- package/dist/avatar.layered.css +1 -1
- package/dist/badge.css +2 -2
- package/dist/badge.layered.css +2 -2
- package/dist/button.css +3 -3
- package/dist/button.layered.css +3 -3
- package/dist/callout.css +6 -0
- package/dist/callout.d.ts +2 -2
- package/dist/callout.layered.css +6 -0
- package/dist/cjs/components/accentpicker/accentpicker.js +66 -0
- package/dist/cjs/components/accentpicker/accentpicker.recipe.js +25 -0
- package/dist/cjs/components/accentpicker/index.js +7 -0
- package/dist/cjs/components/avatar/avatar.recipe.js +4 -1
- package/dist/cjs/components/badge/badge.recipe.js +16 -2
- package/dist/cjs/components/button/button.recipe.js +16 -6
- package/dist/cjs/components/callout/callout.js +2 -2
- package/dist/cjs/components/callout/callout.recipe.js +15 -2
- package/dist/cjs/components/input/input.js +2 -2
- package/dist/cjs/components/input/input.recipe.js +14 -0
- package/dist/cjs/components/menu/menu.js +2 -2
- package/dist/cjs/components/menu/menu.recipe.js +8 -0
- package/dist/cjs/components/multiselect/multiselect.js +23 -10
- package/dist/cjs/components/multiselect/multiselect.recipe.js +104 -65
- package/dist/cjs/components/progress/progress.js +21 -4
- package/dist/cjs/components/progress/progress.recipe.js +30 -0
- package/dist/cjs/components/select/listbox-keyboard.js +7 -1
- package/dist/cjs/components/select/select.js +24 -11
- package/dist/cjs/components/select/select.recipe.js +177 -78
- package/dist/cjs/components/tabletoolbar/tabletoolbar.js +3 -3
- package/dist/cjs/components/tabletoolbar/tabletoolbar.recipe.js +26 -1
- package/dist/cjs/components/tabs/tabs.js +63 -4
- package/dist/cjs/components/tabs/tabs.recipe.js +13 -0
- package/dist/cjs/components/text/text.recipe.js +8 -7
- package/dist/cjs/components/textarea/textarea.js +3 -2
- package/dist/cjs/components/textarea/textarea.recipe.js +2 -1
- package/dist/cjs/components/textlink/textlink.js +2 -2
- package/dist/cjs/components/textlink/textlink.recipe.js +24 -3
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/product/recordpage/recordpage.js +61 -7
- package/dist/cjs/tokens/elevation.js +7 -0
- package/dist/cjs/tokens/palette.js +120 -25
- package/dist/cjs/tokens/scale.js +9 -0
- package/dist/cjs/tokens/semantic.js +42 -0
- package/dist/esm/components/accentpicker/accentpicker.js +30 -0
- package/dist/esm/components/accentpicker/accentpicker.recipe.js +22 -0
- package/dist/esm/components/accentpicker/index.js +2 -0
- package/dist/esm/components/avatar/avatar.recipe.js +4 -1
- package/dist/esm/components/badge/badge.recipe.js +16 -2
- package/dist/esm/components/button/button.recipe.js +16 -6
- package/dist/esm/components/callout/callout.js +2 -2
- package/dist/esm/components/callout/callout.recipe.js +15 -2
- package/dist/esm/components/input/input.js +3 -3
- package/dist/esm/components/input/input.recipe.js +14 -0
- package/dist/esm/components/menu/menu.js +2 -2
- package/dist/esm/components/menu/menu.recipe.js +8 -0
- package/dist/esm/components/multiselect/multiselect.js +23 -10
- package/dist/esm/components/multiselect/multiselect.recipe.js +104 -65
- package/dist/esm/components/progress/progress.js +22 -5
- package/dist/esm/components/progress/progress.recipe.js +30 -0
- package/dist/esm/components/select/listbox-keyboard.js +7 -1
- package/dist/esm/components/select/select.js +24 -11
- package/dist/esm/components/select/select.recipe.js +177 -78
- package/dist/esm/components/tabletoolbar/tabletoolbar.js +3 -3
- package/dist/esm/components/tabletoolbar/tabletoolbar.recipe.js +26 -1
- package/dist/esm/components/tabs/tabs.js +63 -4
- package/dist/esm/components/tabs/tabs.recipe.js +13 -0
- package/dist/esm/components/text/text.recipe.js +8 -7
- package/dist/esm/components/textarea/textarea.js +3 -2
- package/dist/esm/components/textarea/textarea.recipe.js +2 -1
- package/dist/esm/components/textlink/textlink.js +2 -2
- package/dist/esm/components/textlink/textlink.recipe.js +24 -3
- package/dist/esm/index.js +1 -0
- package/dist/esm/product/recordpage/recordpage.js +62 -8
- package/dist/esm/tokens/elevation.js +7 -0
- package/dist/esm/tokens/palette.js +120 -25
- package/dist/esm/tokens/scale.js +9 -0
- package/dist/esm/tokens/semantic.js +42 -0
- package/dist/input.css +11 -0
- package/dist/input.d.ts +2 -2
- package/dist/input.layered.css +11 -0
- package/dist/menu.css +8 -0
- package/dist/menu.layered.css +8 -0
- package/dist/multiselect.css +57 -29
- package/dist/multiselect.d.ts +3 -1
- package/dist/multiselect.layered.css +57 -29
- package/dist/native/tokens.d.ts +1 -1
- package/dist/native/tokens.js +82 -28
- package/dist/progress.css +3 -0
- package/dist/progress.layered.css +3 -0
- package/dist/select.css +100 -42
- package/dist/select.d.ts +3 -2
- package/dist/select.layered.css +100 -42
- package/dist/styles.css +268 -93
- package/dist/styles.layered.css +268 -93
- package/dist/tabletoolbar.css +8 -1
- package/dist/tabletoolbar.layered.css +8 -1
- package/dist/tabs.css +6 -0
- package/dist/tabs.layered.css +6 -0
- package/dist/text.css +1 -1
- package/dist/text.layered.css +1 -1
- package/dist/textarea.css +2 -1
- package/dist/textarea.layered.css +2 -1
- package/dist/textlink.css +11 -2
- package/dist/textlink.d.ts +2 -1
- package/dist/textlink.layered.css +11 -2
- package/dist/tokens.css +43 -11
- package/dist/tokens.json +82 -28
- package/dist/types/components/accentpicker/accentpicker.d.ts +23 -0
- package/dist/types/components/accentpicker/accentpicker.recipe.d.ts +3 -0
- package/dist/types/components/accentpicker/index.d.ts +2 -0
- package/dist/types/components/button/button.recipe.d.ts +2 -2
- package/dist/types/components/callout/callout.d.ts +9 -1
- package/dist/types/components/callout/callout.recipe.d.ts +12 -2
- package/dist/types/components/input/input.d.ts +14 -0
- package/dist/types/components/input/input.recipe.d.ts +3 -0
- package/dist/types/components/menu/menu.d.ts +7 -1
- package/dist/types/components/multiselect/multiselect.d.ts +25 -6
- package/dist/types/components/multiselect/multiselect.recipe.d.ts +27 -0
- package/dist/types/components/progress/progress.d.ts +16 -4
- package/dist/types/components/progress/progress.recipe.d.ts +22 -0
- package/dist/types/components/select/listbox-keyboard.d.ts +10 -1
- package/dist/types/components/select/select.d.ts +29 -6
- package/dist/types/components/select/select.recipe.d.ts +25 -10
- package/dist/types/components/tabletoolbar/tabletoolbar.d.ts +14 -0
- package/dist/types/components/tabs/tabs.d.ts +9 -1
- package/dist/types/components/textarea/textarea.d.ts +16 -0
- package/dist/types/components/textlink/textlink.d.ts +8 -1
- package/dist/types/components/textlink/textlink.recipe.d.ts +10 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/product/recordpage/recordpage.d.ts +61 -1
- package/dist/types/tokens/contract.d.ts +16 -3
- package/dist/types/tokens/elevation.d.ts +7 -0
- package/dist/types/tokens/palette.d.ts +55 -11
- package/dist/types/tokens/scale.d.ts +6 -0
- package/dist/types/tokens/semantic.d.ts +33 -0
- package/package.json +6 -1
|
@@ -39,13 +39,19 @@ export type MenuItemProps = {
|
|
|
39
39
|
children: React.ReactNode;
|
|
40
40
|
icon?: React.ReactNode;
|
|
41
41
|
shortcut?: string;
|
|
42
|
+
/**
|
|
43
|
+
* A trailing count badge (crisp#875) — e.g. a saved-filter item showing
|
|
44
|
+
* how many rows match. Same measured neutral chip `ToolbarTool`'s own
|
|
45
|
+
* `count` prop uses, not bare text.
|
|
46
|
+
*/
|
|
47
|
+
count?: React.ReactNode;
|
|
42
48
|
danger?: boolean;
|
|
43
49
|
disabled?: boolean;
|
|
44
50
|
onSelect?: () => void;
|
|
45
51
|
/** Keep the menu open after selecting (default closes). */
|
|
46
52
|
closeOnSelect?: boolean;
|
|
47
53
|
};
|
|
48
|
-
export declare function MenuItem({ children, icon, shortcut, danger, disabled, onSelect, closeOnSelect, }: MenuItemProps): React.JSX.Element;
|
|
54
|
+
export declare function MenuItem({ children, icon, shortcut, count, danger, disabled, onSelect, closeOnSelect, }: MenuItemProps): React.JSX.Element;
|
|
49
55
|
export declare namespace MenuItem {
|
|
50
56
|
var displayName: string;
|
|
51
57
|
}
|
|
@@ -45,18 +45,37 @@ export type MultiSelectProps = Omit<React.ComponentPropsWithoutRef<"div">, "valu
|
|
|
45
45
|
/** Shown when the search matches nothing. */
|
|
46
46
|
emptyLabel?: string;
|
|
47
47
|
disabled?: boolean;
|
|
48
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Answered and locked, not editable — unlike `disabled`, the trigger stays
|
|
50
|
+
* focusable (crisp/#882, matching `Select`'s `readOnly`).
|
|
51
|
+
*/
|
|
52
|
+
readOnly?: boolean;
|
|
53
|
+
/** 2px red border + `aria-invalid`, matching `Input`'s and `Select`'s. */
|
|
49
54
|
invalid?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* `small` (default, crisp/#889) is Attio's own 32px trigger floor — lines
|
|
57
|
+
* up with `Input`'s own size. `medium`/`large` are seed-design's own
|
|
58
|
+
* 40px/52px floors (crisp/#882), opt-in. Purely visual.
|
|
59
|
+
*/
|
|
60
|
+
size?: "small" | "medium" | "large";
|
|
61
|
+
/**
|
|
62
|
+
* `ghost` fills whatever row it's embedded in instead of the fixed
|
|
63
|
+
* trigger height — for inline table cell editors (crisp/#882, matching
|
|
64
|
+
* `Select`'s `variant`).
|
|
65
|
+
*/
|
|
66
|
+
variant?: "default" | "ghost";
|
|
50
67
|
className?: string;
|
|
51
68
|
"aria-label"?: string;
|
|
52
69
|
};
|
|
53
70
|
/**
|
|
54
|
-
* A multi-select / tag editor
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
71
|
+
* A multi-select / tag editor, its trigger/listbox/item chrome built to the
|
|
72
|
+
* same seed-design parity as `Select` (crisp/#882, following #867/#879) —
|
|
73
|
+
* its own chip/checkbox picker behaviour is unchanged. The outlined trigger
|
|
74
|
+
* shows the selected values as coloured chips; it opens a popover with a
|
|
75
|
+
* search field over rows of "[chip] … [checkbox]" that toggle on click (the
|
|
76
|
+
* menu stays open). Keyboard: ↑/↓ move, Enter/Space toggle, Esc closes.
|
|
58
77
|
*/
|
|
59
|
-
export declare function MultiSelect({ options, value: valueProp, defaultValue, onValueChange, name, required, id, placeholder: placeholderProp, searchable, searchPlaceholder: searchPlaceholderProp, emptyLabel: emptyLabelProp, disabled, invalid, className, "aria-label": ariaLabel, ...rest }: MultiSelectProps): React.JSX.Element;
|
|
78
|
+
export declare function MultiSelect({ options, value: valueProp, defaultValue, onValueChange, name, required, id, placeholder: placeholderProp, searchable, searchPlaceholder: searchPlaceholderProp, emptyLabel: emptyLabelProp, disabled, readOnly, invalid, size, variant, className, "aria-label": ariaLabel, ...rest }: MultiSelectProps): React.JSX.Element;
|
|
60
79
|
export declare namespace MultiSelect {
|
|
61
80
|
var displayName: string;
|
|
62
81
|
}
|
|
@@ -1,20 +1,47 @@
|
|
|
1
1
|
declare const config: import("../..").RecipeConfig<{
|
|
2
|
+
size: {
|
|
3
|
+
small: string;
|
|
4
|
+
medium: string;
|
|
5
|
+
large: string;
|
|
6
|
+
};
|
|
2
7
|
invalid: {
|
|
3
8
|
true: string;
|
|
4
9
|
false: string;
|
|
5
10
|
};
|
|
11
|
+
variant: {
|
|
12
|
+
default: string;
|
|
13
|
+
ghost: string;
|
|
14
|
+
};
|
|
6
15
|
}>;
|
|
7
16
|
export declare const multiselectRecipe: import("../..").RecipeFn<{
|
|
17
|
+
size: {
|
|
18
|
+
small: string;
|
|
19
|
+
medium: string;
|
|
20
|
+
large: string;
|
|
21
|
+
};
|
|
8
22
|
invalid: {
|
|
9
23
|
true: string;
|
|
10
24
|
false: string;
|
|
11
25
|
};
|
|
26
|
+
variant: {
|
|
27
|
+
default: string;
|
|
28
|
+
ghost: string;
|
|
29
|
+
};
|
|
12
30
|
}> & {
|
|
13
31
|
config: import("../..").RecipeConfig<{
|
|
32
|
+
size: {
|
|
33
|
+
small: string;
|
|
34
|
+
medium: string;
|
|
35
|
+
large: string;
|
|
36
|
+
};
|
|
14
37
|
invalid: {
|
|
15
38
|
true: string;
|
|
16
39
|
false: string;
|
|
17
40
|
};
|
|
41
|
+
variant: {
|
|
42
|
+
default: string;
|
|
43
|
+
ghost: string;
|
|
44
|
+
};
|
|
18
45
|
}>;
|
|
19
46
|
};
|
|
20
47
|
export default config;
|
|
@@ -5,15 +5,27 @@ export type ProgressProps = React.ComponentPropsWithoutRef<"div"> & {
|
|
|
5
5
|
max?: number;
|
|
6
6
|
/** Render as N discrete segments (a step bar) instead of a continuous fill. */
|
|
7
7
|
segments?: number;
|
|
8
|
+
/**
|
|
9
|
+
* `"linear"` (default) or `"circular"` — a small ring, measured live on
|
|
10
|
+
* Attio's own Settings > Profile character-counter (crisp#634).
|
|
11
|
+
*/
|
|
12
|
+
variant?: "linear" | "circular";
|
|
13
|
+
/**
|
|
14
|
+
* Circular only: outer diameter in px. Default 18 is Attio's own measured
|
|
15
|
+
* size; `strokeWidth` scales proportionally at other sizes (18px's own
|
|
16
|
+
* 1.6px ratio) since only the one size was ever measured.
|
|
17
|
+
*/
|
|
18
|
+
size?: number;
|
|
8
19
|
"aria-label"?: string;
|
|
9
20
|
className?: string;
|
|
10
21
|
};
|
|
11
22
|
/**
|
|
12
|
-
* A progress bar — a continuous brand fill,
|
|
13
|
-
* `segments` is set (the "Getting started 3/6" pattern)
|
|
14
|
-
* `
|
|
23
|
+
* A progress bar — a continuous brand fill, a segmented row of pills when
|
|
24
|
+
* `segments` is set (the "Getting started 3/6" pattern), or a small ring
|
|
25
|
+
* (`variant="circular"`, a character-counter's own progress). Reports its
|
|
26
|
+
* state via `role="progressbar"` and the ARIA value attributes.
|
|
15
27
|
*/
|
|
16
|
-
export declare function Progress({ value, max, segments, "aria-label": ariaLabel, className, ...rest }: ProgressProps): import("react").JSX.Element;
|
|
28
|
+
export declare function Progress({ value, max, segments, variant, size, "aria-label": ariaLabel, className, ...rest }: ProgressProps): import("react").JSX.Element;
|
|
17
29
|
export declare namespace Progress {
|
|
18
30
|
var displayName: string;
|
|
19
31
|
}
|
|
@@ -42,6 +42,28 @@ declare const spec: {
|
|
|
42
42
|
readonly decls: {
|
|
43
43
|
background: `var(--${string})`;
|
|
44
44
|
};
|
|
45
|
+
}, {
|
|
46
|
+
readonly selector: "&[data-variant=\"circular\"]";
|
|
47
|
+
readonly decls: {
|
|
48
|
+
readonly display: "inline-flex";
|
|
49
|
+
readonly height: "auto";
|
|
50
|
+
readonly borderRadius: "0";
|
|
51
|
+
readonly background: "transparent";
|
|
52
|
+
readonly overflow: "visible";
|
|
53
|
+
};
|
|
54
|
+
}, {
|
|
55
|
+
readonly slot: "circleTrack";
|
|
56
|
+
readonly selector: "& .crisp-progress-circle-track";
|
|
57
|
+
readonly decls: {
|
|
58
|
+
readonly stroke: `color-mix(in srgb, var(--${string}) 14%, transparent)`;
|
|
59
|
+
};
|
|
60
|
+
}, {
|
|
61
|
+
readonly slot: "circleFill";
|
|
62
|
+
readonly selector: "& .crisp-progress-circle-fill";
|
|
63
|
+
readonly decls: {
|
|
64
|
+
readonly stroke: `var(--${string})`;
|
|
65
|
+
readonly transition: "stroke-dashoffset 0.25s ease";
|
|
66
|
+
};
|
|
45
67
|
}];
|
|
46
68
|
};
|
|
47
69
|
declare const config: import("../..").RecipeConfig<Record<string, Record<string, string>>>;
|
|
@@ -19,6 +19,15 @@ export type UseListboxKeyboardOptions = {
|
|
|
19
19
|
* lands the user in the wrong place. Defaults to `close`.
|
|
20
20
|
*/
|
|
21
21
|
dismiss?: () => void;
|
|
22
|
+
/**
|
|
23
|
+
* Space also commits the highlighted option, matching seed-design's
|
|
24
|
+
* Select (crisp/#867: Enter AND Space both commit) and native `<select>`.
|
|
25
|
+
* Defaults `false` because this same hook wires a `searchable` popup's own
|
|
26
|
+
* text input — there, Space must stay a normal character, never a commit.
|
|
27
|
+
* Pass `true` only when the element this hook is bound to is NOT a text
|
|
28
|
+
* field (the trigger itself, when not `searchable`).
|
|
29
|
+
*/
|
|
30
|
+
commitOnSpace?: boolean;
|
|
22
31
|
};
|
|
23
32
|
/**
|
|
24
33
|
* The WAI-ARIA listbox keyboard model for a POPUP listbox: ↑/↓ to move the
|
|
@@ -33,6 +42,6 @@ export type UseListboxKeyboardOptions = {
|
|
|
33
42
|
* NOT for `WheelPicker`: that is an always-visible multi-column wheel that
|
|
34
43
|
* commits on move, so Enter, Escape and Tab have no meaning in it.
|
|
35
44
|
*/
|
|
36
|
-
export declare function useListboxKeyboard({ enabledIndexes, highlight, setHighlight, commit, close, dismiss, }: UseListboxKeyboardOptions): {
|
|
45
|
+
export declare function useListboxKeyboard({ enabledIndexes, highlight, setHighlight, commit, close, dismiss, commitOnSpace, }: UseListboxKeyboardOptions): {
|
|
37
46
|
onKeyDown: (e: React.KeyboardEvent) => void;
|
|
38
47
|
};
|
|
@@ -20,6 +20,12 @@ export type SelectOption = {
|
|
|
20
20
|
* with no `group` render exactly as before this existed.
|
|
21
21
|
*/
|
|
22
22
|
group?: string;
|
|
23
|
+
/**
|
|
24
|
+
* A second line under `label` (crisp/#867, seed-design's `SelectItem`
|
|
25
|
+
* label + description). Omit for the plain single-line row every existing
|
|
26
|
+
* consumer already renders.
|
|
27
|
+
*/
|
|
28
|
+
description?: React.ReactNode;
|
|
23
29
|
};
|
|
24
30
|
export type SelectProps = Omit<React.ComponentPropsWithoutRef<"div">, "value" | "defaultValue" | "onChange"> & {
|
|
25
31
|
options: SelectOption[];
|
|
@@ -49,6 +55,20 @@ export type SelectProps = Omit<React.ComponentPropsWithoutRef<"div">, "value" |
|
|
|
49
55
|
variant?: "default" | "ghost";
|
|
50
56
|
/** `full` (default) fills its container; `auto` sizes to content. */
|
|
51
57
|
width?: "full" | "auto";
|
|
58
|
+
/**
|
|
59
|
+
* `small` (default, crisp/#889) is Attio's own 32px trigger height — lines
|
|
60
|
+
* up with `Input`'s own size, since the two sit side by side in every
|
|
61
|
+
* form. `medium`/`large` are seed-design's own 40px/52px (crisp/#867),
|
|
62
|
+
* opt-in where the surrounding layout calls for a bigger control. Purely
|
|
63
|
+
* visual — the listbox/item chrome is identical across all three.
|
|
64
|
+
*/
|
|
65
|
+
size?: "small" | "medium" | "large";
|
|
66
|
+
/**
|
|
67
|
+
* Answered and locked, not editable — unlike `disabled`, the trigger stays
|
|
68
|
+
* focusable and its text stays full-strength ink (crisp/#867, seed-design's
|
|
69
|
+
* `readonly` state: the fill greys like `disabled`, the text doesn't).
|
|
70
|
+
*/
|
|
71
|
+
readOnly?: boolean;
|
|
52
72
|
/** Show a search field at the top of the list that filters options (Linear/cmdk style). */
|
|
53
73
|
searchable?: boolean;
|
|
54
74
|
searchPlaceholder?: string;
|
|
@@ -68,13 +88,16 @@ export type SelectProps = Omit<React.ComponentPropsWithoutRef<"div">, "value" |
|
|
|
68
88
|
id?: string;
|
|
69
89
|
};
|
|
70
90
|
/**
|
|
71
|
-
* A select / dropdown
|
|
72
|
-
*
|
|
73
|
-
* `
|
|
74
|
-
*
|
|
75
|
-
*
|
|
91
|
+
* A select / dropdown, built to seed-design's Select (crisp/#867) rather than
|
|
92
|
+
* measured from Attio — a deliberate one-component exception, the same way
|
|
93
|
+
* `DatePicker` follows seed's calendar structure — with an optional
|
|
94
|
+
* Linear-style search seed itself has no equivalent of. A `role="combobox"`
|
|
95
|
+
* trigger opens a `role="listbox"`; pass `searchable` to add a filter field
|
|
96
|
+
* at the top (with a "No results" empty state). Full keyboard model — ↑/↓
|
|
97
|
+
* move, Enter/Space pick, Esc close, Home/End jump, opens upward when tight.
|
|
98
|
+
* Controlled or uncontrolled.
|
|
76
99
|
*/
|
|
77
|
-
export declare function Select({ options, value, defaultValue, onValueChange, name, required, placeholder: placeholderProp, variant, width, searchable, searchPlaceholder: searchPlaceholderProp, onSearchChange, emptyLabel: emptyLabelProp, disabled, invalid, className, "aria-label": ariaLabel, id, ...rest }: SelectProps): React.JSX.Element;
|
|
100
|
+
export declare function Select({ options, value, defaultValue, onValueChange, name, required, placeholder: placeholderProp, variant, width, size, searchable, searchPlaceholder: searchPlaceholderProp, onSearchChange, emptyLabel: emptyLabelProp, disabled, readOnly, invalid, className, "aria-label": ariaLabel, id, ...rest }: SelectProps): React.JSX.Element;
|
|
78
101
|
export declare namespace Select {
|
|
79
102
|
var displayName: string;
|
|
80
103
|
}
|
|
@@ -1,44 +1,59 @@
|
|
|
1
1
|
declare const config: import("../..").RecipeConfig<{
|
|
2
|
-
variant: {
|
|
3
|
-
default: string;
|
|
4
|
-
ghost: string;
|
|
5
|
-
};
|
|
6
2
|
width: {
|
|
7
3
|
full: string;
|
|
8
4
|
auto: string;
|
|
9
5
|
};
|
|
6
|
+
size: {
|
|
7
|
+
small: string;
|
|
8
|
+
medium: string;
|
|
9
|
+
large: string;
|
|
10
|
+
};
|
|
10
11
|
invalid: {
|
|
11
12
|
true: string;
|
|
12
13
|
false: string;
|
|
13
14
|
};
|
|
14
|
-
}>;
|
|
15
|
-
export declare const selectRecipe: import("../..").RecipeFn<{
|
|
16
15
|
variant: {
|
|
17
16
|
default: string;
|
|
18
17
|
ghost: string;
|
|
19
18
|
};
|
|
19
|
+
}>;
|
|
20
|
+
export declare const selectRecipe: import("../..").RecipeFn<{
|
|
20
21
|
width: {
|
|
21
22
|
full: string;
|
|
22
23
|
auto: string;
|
|
23
24
|
};
|
|
25
|
+
size: {
|
|
26
|
+
small: string;
|
|
27
|
+
medium: string;
|
|
28
|
+
large: string;
|
|
29
|
+
};
|
|
24
30
|
invalid: {
|
|
25
31
|
true: string;
|
|
26
32
|
false: string;
|
|
27
33
|
};
|
|
34
|
+
variant: {
|
|
35
|
+
default: string;
|
|
36
|
+
ghost: string;
|
|
37
|
+
};
|
|
28
38
|
}> & {
|
|
29
39
|
config: import("../..").RecipeConfig<{
|
|
30
|
-
variant: {
|
|
31
|
-
default: string;
|
|
32
|
-
ghost: string;
|
|
33
|
-
};
|
|
34
40
|
width: {
|
|
35
41
|
full: string;
|
|
36
42
|
auto: string;
|
|
37
43
|
};
|
|
44
|
+
size: {
|
|
45
|
+
small: string;
|
|
46
|
+
medium: string;
|
|
47
|
+
large: string;
|
|
48
|
+
};
|
|
38
49
|
invalid: {
|
|
39
50
|
true: string;
|
|
40
51
|
false: string;
|
|
41
52
|
};
|
|
53
|
+
variant: {
|
|
54
|
+
default: string;
|
|
55
|
+
ghost: string;
|
|
56
|
+
};
|
|
42
57
|
}>;
|
|
43
58
|
};
|
|
44
59
|
export default config;
|
|
@@ -320,6 +320,13 @@ export type ToolbarToolProps = React.ComponentPropsWithoutRef<"button"> & {
|
|
|
320
320
|
/** The quieter, no-ring variant Sort/Filter never use themselves, for a
|
|
321
321
|
* chip whose "on" state should read as less committed than a real filter. */
|
|
322
322
|
ghost?: boolean;
|
|
323
|
+
/**
|
|
324
|
+
* A trailing count badge (crisp#875) — a screen's own quick filter
|
|
325
|
+
* showing how many rows match, e.g. "My tasks 5". Measured live on two
|
|
326
|
+
* independent Attio surfaces (the Sort tool's own "+N" overflow, a Kanban
|
|
327
|
+
* board's stage-column count): a small neutral chip, not bare text.
|
|
328
|
+
*/
|
|
329
|
+
count?: React.ReactNode;
|
|
323
330
|
};
|
|
324
331
|
/**
|
|
325
332
|
* The Sort/Filter chip's own chrome (`.crisp-tabletoolbar-tool`), standalone
|
|
@@ -337,5 +344,12 @@ export declare const ToolbarTool: React.ForwardRefExoticComponent<Omit<React.Det
|
|
|
337
344
|
/** The quieter, no-ring variant Sort/Filter never use themselves, for a
|
|
338
345
|
* chip whose "on" state should read as less committed than a real filter. */
|
|
339
346
|
ghost?: boolean;
|
|
347
|
+
/**
|
|
348
|
+
* A trailing count badge (crisp#875) — a screen's own quick filter
|
|
349
|
+
* showing how many rows match, e.g. "My tasks 5". Measured live on two
|
|
350
|
+
* independent Attio surfaces (the Sort tool's own "+N" overflow, a Kanban
|
|
351
|
+
* board's stage-column count): a small neutral chip, not bare text.
|
|
352
|
+
*/
|
|
353
|
+
count?: React.ReactNode;
|
|
340
354
|
} & React.RefAttributes<HTMLButtonElement>>;
|
|
341
355
|
export {};
|
|
@@ -20,6 +20,14 @@ export type TabsProps = Omit<React.ComponentPropsWithoutRef<"div">, "value" | "d
|
|
|
20
20
|
leading?: React.ReactNode;
|
|
21
21
|
/** Rendered for the active tab. Receives the active value. */
|
|
22
22
|
children?: (value: string) => React.ReactNode;
|
|
23
|
+
/**
|
|
24
|
+
* The "+N more" overflow trigger's own label (crisp#863, confirmed live:
|
|
25
|
+
* Attio's own copy is exactly "+N more", a chevron after it). Receives
|
|
26
|
+
* the hidden-tab count. Defaults to that measured copy.
|
|
27
|
+
*/
|
|
28
|
+
moreLabel?: (count: number) => React.ReactNode;
|
|
29
|
+
/** aria-label on the overflow trigger/menu (default "More tabs"). */
|
|
30
|
+
moreMenuLabel?: string;
|
|
23
31
|
className?: string;
|
|
24
32
|
"aria-label"?: string;
|
|
25
33
|
};
|
|
@@ -29,7 +37,7 @@ export type TabsProps = Omit<React.ComponentPropsWithoutRef<"div">, "value" | "d
|
|
|
29
37
|
* Home/End jump); activation follows focus. Controlled via
|
|
30
38
|
* `value`/`onValueChange`, or uncontrolled from `defaultValue`.
|
|
31
39
|
*/
|
|
32
|
-
export declare function Tabs({ tabs, value, defaultValue, onValueChange, leading, children, className, fill, "aria-label": ariaLabel, ...rest }: TabsProps): React.JSX.Element;
|
|
40
|
+
export declare function Tabs({ tabs, value, defaultValue, onValueChange, leading, children, moreLabel, moreMenuLabel, className, fill, "aria-label": ariaLabel, ...rest }: TabsProps): React.JSX.Element;
|
|
33
41
|
export declare namespace Tabs {
|
|
34
42
|
var displayName: string;
|
|
35
43
|
}
|
|
@@ -2,6 +2,14 @@ import * as React from "react";
|
|
|
2
2
|
export type TextareaProps = React.ComponentPropsWithoutRef<"textarea"> & {
|
|
3
3
|
/** Show a "N / maxLength" counter bottom-right (also caps input at maxLength). */
|
|
4
4
|
showCount?: boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Pair the counter with a small circular progress ring (crisp#634),
|
|
7
|
+
* measured live on Attio's own Settings > Profile "Personal context"
|
|
8
|
+
* field. Only meaningful alongside `showCount`+`maxLength` — not every
|
|
9
|
+
* counted textarea in Attio has one, so this is opt-in rather than tied
|
|
10
|
+
* to `showCount` itself.
|
|
11
|
+
*/
|
|
12
|
+
showProgress?: boolean;
|
|
5
13
|
/** Extra class on the wrapper. */
|
|
6
14
|
wrapperClassName?: string;
|
|
7
15
|
};
|
|
@@ -13,6 +21,14 @@ export type TextareaProps = React.ComponentPropsWithoutRef<"textarea"> & {
|
|
|
13
21
|
export declare const Textarea: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.TextareaHTMLAttributes<HTMLTextAreaElement>, HTMLTextAreaElement>, "ref"> & {
|
|
14
22
|
/** Show a "N / maxLength" counter bottom-right (also caps input at maxLength). */
|
|
15
23
|
showCount?: boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Pair the counter with a small circular progress ring (crisp#634),
|
|
26
|
+
* measured live on Attio's own Settings > Profile "Personal context"
|
|
27
|
+
* field. Only meaningful alongside `showCount`+`maxLength` — not every
|
|
28
|
+
* counted textarea in Attio has one, so this is opt-in rather than tied
|
|
29
|
+
* to `showCount` itself.
|
|
30
|
+
*/
|
|
31
|
+
showProgress?: boolean;
|
|
16
32
|
/** Extra class on the wrapper. */
|
|
17
33
|
wrapperClassName?: string;
|
|
18
34
|
} & React.RefAttributes<HTMLTextAreaElement>>;
|
|
@@ -4,6 +4,13 @@ export type TextLinkProps = React.ComponentPropsWithoutRef<"a"> & {
|
|
|
4
4
|
* `"muted"` (default) — quiet until hover, then brand-coloured (an
|
|
5
5
|
* in-context reference link, e.g. a sample record under a finding). */
|
|
6
6
|
tone?: "brand" | "muted";
|
|
7
|
+
/**
|
|
8
|
+
* Overrides the tone's own font-size only (colour/weight/hover stay
|
|
9
|
+
* whatever `tone` gives). Omit it and each tone keeps its existing size
|
|
10
|
+
* unchanged — `brand`'s 12px, `muted`'s 13px. `"lg"` (14px) matches a
|
|
11
|
+
* `DataTable` primary-column's own ambient size (crisp#874).
|
|
12
|
+
*/
|
|
13
|
+
size?: "sm" | "md" | "lg";
|
|
7
14
|
className?: string;
|
|
8
15
|
};
|
|
9
16
|
/**
|
|
@@ -13,7 +20,7 @@ export type TextLinkProps = React.ComponentPropsWithoutRef<"a"> & {
|
|
|
13
20
|
* `event.preventDefault()` pairs it with client-side routing (e.g.
|
|
14
21
|
* react-router's own `Link`).
|
|
15
22
|
*/
|
|
16
|
-
export declare function TextLink({ tone, className, ...rest }: TextLinkProps): React.JSX.Element;
|
|
23
|
+
export declare function TextLink({ tone, size, className, ...rest }: TextLinkProps): React.JSX.Element;
|
|
17
24
|
export declare namespace TextLink {
|
|
18
25
|
var displayName: string;
|
|
19
26
|
}
|
|
@@ -3,11 +3,21 @@ declare const config: import("../..").RecipeConfig<{
|
|
|
3
3
|
brand: string;
|
|
4
4
|
muted: string;
|
|
5
5
|
};
|
|
6
|
+
size: {
|
|
7
|
+
sm: string;
|
|
8
|
+
md: string;
|
|
9
|
+
lg: string;
|
|
10
|
+
};
|
|
6
11
|
}>;
|
|
7
12
|
export declare const textlinkRecipe: import("../..").RecipeFn<{
|
|
8
13
|
tone: {
|
|
9
14
|
brand: string;
|
|
10
15
|
muted: string;
|
|
11
16
|
};
|
|
17
|
+
size: {
|
|
18
|
+
sm: string;
|
|
19
|
+
md: string;
|
|
20
|
+
lg: string;
|
|
21
|
+
};
|
|
12
22
|
}>;
|
|
13
23
|
export default config;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type LucideIcon } from "lucide-react";
|
|
2
2
|
import * as React from "react";
|
|
3
|
+
import { type CommentAuthor, type CommentThread } from "../comments";
|
|
3
4
|
import { type Column, type Row } from "./column";
|
|
4
5
|
export type RecordPageNote = {
|
|
5
6
|
id: string;
|
|
@@ -57,6 +58,17 @@ export type RecordPageHighlight = {
|
|
|
57
58
|
value: React.ReactNode | null;
|
|
58
59
|
empty?: React.ReactNode;
|
|
59
60
|
};
|
|
61
|
+
/**
|
|
62
|
+
* One icon button in the quick-action row (#865) — "New note"/"Run
|
|
63
|
+
* workflow"/"New task" in the built-in CRM set. `label` doubles as the
|
|
64
|
+
* button's `aria-label`, since these render icon-only (measured live: no
|
|
65
|
+
* visible text next to any of the three, only a native-title tooltip).
|
|
66
|
+
*/
|
|
67
|
+
export type RecordPageQuickAction = {
|
|
68
|
+
label: string;
|
|
69
|
+
icon: LucideIcon;
|
|
70
|
+
onSelect?: () => void;
|
|
71
|
+
};
|
|
60
72
|
export type RecordPageProps = Omit<React.ComponentPropsWithoutRef<"div">, "children"> & {
|
|
61
73
|
record: Row;
|
|
62
74
|
columns: Column[];
|
|
@@ -90,6 +102,18 @@ export type RecordPageProps = Omit<React.ComponentPropsWithoutRef<"div">, "child
|
|
|
90
102
|
tabs?: RecordPageTab[];
|
|
91
103
|
/** Active tab id on first render, when `tabs` is supplied. Defaults to the first tab. Ignored for the built-in tab set (Overview is always first there). */
|
|
92
104
|
defaultTab?: string;
|
|
105
|
+
/**
|
|
106
|
+
* Replaces the quick-action row's icon buttons (New note / Run workflow /
|
|
107
|
+
* New task) — the same "caller's own list, not a merge" choice `tabs`
|
|
108
|
+
* (#379) and `highlights` (#528) already make. Confirmed live this set
|
|
109
|
+
* varies by object type (#865): a Person record carries a 4th,
|
|
110
|
+
* unidentified icon that Company and Deal records don't, so a consumer
|
|
111
|
+
* targeting a non-CRM object supplies its own icons rather than crisp
|
|
112
|
+
* guessing at a superset. The row's two text buttons ("Compose email",
|
|
113
|
+
* "Add to list") aren't part of this override — discovery found no
|
|
114
|
+
* variance there, only in the icon set. Omit to keep the built-in three.
|
|
115
|
+
*/
|
|
116
|
+
quickActions?: RecordPageQuickAction[];
|
|
93
117
|
/**
|
|
94
118
|
* Controlled Notes: when supplied (even as `[]`), RecordPage renders
|
|
95
119
|
* this list instead of managing its own, and the composer calls
|
|
@@ -120,6 +144,29 @@ export type RecordPageProps = Omit<React.ComponentPropsWithoutRef<"div">, "child
|
|
|
120
144
|
* the built-in CRM set.
|
|
121
145
|
*/
|
|
122
146
|
highlights?: RecordPageHighlight[] | false;
|
|
147
|
+
/**
|
|
148
|
+
* Wires the header's Comments entry point (#864) to crisp's own,
|
|
149
|
+
* already-closed `product/comments` panel (#625) — the gap #864 found
|
|
150
|
+
* wasn't the comments feature itself, only that `RecordPage` never
|
|
151
|
+
* opened it. Controlled the same way `notes`/`tasks` are: supply this
|
|
152
|
+
* (even `[]`) and `onPostComment` to own the data yourself; omit both to
|
|
153
|
+
* let `RecordPage` keep a small self-contained thread list, same as its
|
|
154
|
+
* default Notes/Tasks behaviour.
|
|
155
|
+
*/
|
|
156
|
+
comments?: CommentThread[];
|
|
157
|
+
onPostComment?: (text: string, threadId: string | null) => void;
|
|
158
|
+
/**
|
|
159
|
+
* Attributes a self-managed comment's `author` (id/name/avatar) — has no
|
|
160
|
+
* effect when `comments` is controlled, since then every thread's author
|
|
161
|
+
* is already the caller's own data. Defaults to a synthetic "You", same
|
|
162
|
+
* as Notes/Tasks already show for a comment-less consumer.
|
|
163
|
+
*/
|
|
164
|
+
currentUser?: CommentAuthor;
|
|
165
|
+
/** Called when the header's Share button is clicked. Renders regardless
|
|
166
|
+
* (matching Compose email/Add to list's own no-op-until-wired
|
|
167
|
+
* convention) — Attio's own Share opens a dialog crisp has no measured
|
|
168
|
+
* content for; only the entry point is in scope here (#864). */
|
|
169
|
+
onShare?: () => void;
|
|
123
170
|
};
|
|
124
171
|
/**
|
|
125
172
|
* Every chrome string RecordPage renders. Supplied as a PARTIAL map, so
|
|
@@ -138,16 +185,29 @@ export type RecordPageLabels = {
|
|
|
138
185
|
addToFavourites: string;
|
|
139
186
|
removeFromFavourites: string;
|
|
140
187
|
copyRecordLink: string;
|
|
188
|
+
/** "…" record actions menu (#621): configure the record page's layout. */
|
|
189
|
+
configurePage: string;
|
|
190
|
+
/** "…" record actions menu (#621): copy this page's own URL. */
|
|
191
|
+
copyPageUrl: string;
|
|
192
|
+
/** "…" record actions menu (#621): copy the record's raw id. */
|
|
193
|
+
copyRecordId: string;
|
|
194
|
+
/** "…" record actions menu (#621): merge this record into another. */
|
|
195
|
+
mergeRecords: string;
|
|
141
196
|
deleteRecord: string;
|
|
142
197
|
linkRecords: string;
|
|
143
198
|
logANote: string;
|
|
144
199
|
createATask: string;
|
|
200
|
+
runWorkflow: string;
|
|
145
201
|
fullScreen: string;
|
|
146
202
|
exitFullScreen: string;
|
|
147
203
|
resizeDetails: string;
|
|
148
204
|
composeEmail: string;
|
|
149
205
|
askAttio: string;
|
|
150
206
|
addToList: string;
|
|
207
|
+
/** The header's text-only Share button (#864, measured: no icon). */
|
|
208
|
+
share: string;
|
|
209
|
+
/** aria-label on the header's Comments icon button (#864). */
|
|
210
|
+
comments: string;
|
|
151
211
|
/** Empty state under the Lists panel. */
|
|
152
212
|
noLists: string;
|
|
153
213
|
highlights: string;
|
|
@@ -244,7 +304,7 @@ export declare namespace RecordDetails {
|
|
|
244
304
|
* Emails sections (Notes & Tasks are live — add and check things off). Drop it
|
|
245
305
|
* into the app's main content area.
|
|
246
306
|
*/
|
|
247
|
-
export declare function RecordPage({ record, columns, collection, labels, onBack, onToggleFull, full, className, onEdit, tabs: tabsProp, defaultTab, notes: notesProp, onAddNote, tasks: tasksProp, onAddTask, onToggleTask, sections, highlights: highlightsProp, ...rest }: RecordPageProps): React.JSX.Element;
|
|
307
|
+
export declare function RecordPage({ record, columns, collection, labels, onBack, onToggleFull, full, className, onEdit, tabs: tabsProp, defaultTab, notes: notesProp, onAddNote, tasks: tasksProp, onAddTask, onToggleTask, sections, highlights: highlightsProp, quickActions: quickActionsProp, comments: commentsProp, onPostComment, currentUser, onShare, ...rest }: RecordPageProps): React.JSX.Element;
|
|
248
308
|
export declare namespace RecordPage {
|
|
249
309
|
var displayName: string;
|
|
250
310
|
}
|
|
@@ -3,6 +3,8 @@ export type Theme = "light" | "dark";
|
|
|
3
3
|
export declare const contract: MapLeafNodes<{
|
|
4
4
|
bgBrandSolid: "brand600";
|
|
5
5
|
bgBrandSolidPressed: "brand700";
|
|
6
|
+
bgBrandContrast: "brandContrast";
|
|
7
|
+
fgBrandContrast: "brandContrast";
|
|
6
8
|
fgOnBrand: "white";
|
|
7
9
|
fgOnTone: "ink";
|
|
8
10
|
bgSurface: "gray00";
|
|
@@ -43,6 +45,7 @@ export declare const contract: MapLeafNodes<{
|
|
|
43
45
|
strokeFocusRing: "focusRing";
|
|
44
46
|
bgSuccess: "green600";
|
|
45
47
|
bgWarning: "amber600";
|
|
48
|
+
bgWarningSolid: "amberSolid";
|
|
46
49
|
bgOrange: "orange600";
|
|
47
50
|
bgCyan: "cyan600";
|
|
48
51
|
bgPurple: "purple600";
|
|
@@ -56,10 +59,20 @@ export declare const contract: MapLeafNodes<{
|
|
|
56
59
|
bgPurpleSoft: "purpleTint";
|
|
57
60
|
fgPurpleSoft: "softPurpleText";
|
|
58
61
|
ringPurpleSoft: "purpleRing";
|
|
62
|
+
ringBrandSoft: "ringBrandSoft";
|
|
63
|
+
fgSelectNeutral: "fieldFocus";
|
|
64
|
+
bgSelectListbox: "selectListboxBg";
|
|
65
|
+
strokeSelectTrigger: "selectTriggerStroke";
|
|
66
|
+
bgSelectPressed: "selectPressedTint";
|
|
67
|
+
bgSelectDisabled: "selectDisabledBg";
|
|
68
|
+
strokeSelectInvalid: "selectInvalidStroke";
|
|
69
|
+
strokeSelectDivider: "selectDivider";
|
|
70
|
+
fgSelectPlaceholder: "selectPlaceholder";
|
|
71
|
+
shadowSelect: "selectShadow";
|
|
59
72
|
}, `var(--${string})`> & {
|
|
60
|
-
space: Record<"0.5" | "1" | "1.5" | "2" | "2.5" | "3" | "4" | "5" | "6" | "8" | "px", `var(--${string})`>;
|
|
61
|
-
radius: Record<"2xl" | "chip" | "full" | "lg" | "md" | "sm" | "xl", `var(--${string})`>;
|
|
62
|
-
size: Record<"calendarCell" | "calendarPill" | "chip" | "header" | "icon" | "menuRow" | "row" | "tableHeader" | "tableRow", `var(--${string})`>;
|
|
73
|
+
space: Record<"0.5" | "1" | "1.5" | "2" | "2.5" | "3" | "3.5" | "4" | "5" | "6" | "8" | "px", `var(--${string})`>;
|
|
74
|
+
radius: Record<"2xl" | "3xl" | "chip" | "full" | "lg" | "md" | "sm" | "xl" | "xs", `var(--${string})`>;
|
|
75
|
+
size: Record<"calendarCell" | "calendarPill" | "chip" | "header" | "icon" | "menuRow" | "row" | "selectIconLg" | "selectTriggerLg" | "selectTriggerMd" | "tableHeader" | "tableRow", `var(--${string})`>;
|
|
63
76
|
font: Record<"sans", `var(--${string})`>;
|
|
64
77
|
text: Record<"lg" | "md" | "sm" | "xl" | "xs", `var(--${string})`>;
|
|
65
78
|
weight: Record<"bold" | "medium" | "regular" | "semibold", `var(--${string})`>;
|
|
@@ -55,5 +55,12 @@ export declare const elevation: {
|
|
|
55
55
|
* nobody measured for them.
|
|
56
56
|
*/
|
|
57
57
|
readonly fieldNoRing: `0 0 2px rgba(28,40,64,0.18), 0 1px 3px rgba(0,0,0,0.04)`;
|
|
58
|
+
/**
|
|
59
|
+
* Select's own listbox shadow (crisp/#867) — seed-design's `$shadow.s3`, a
|
|
60
|
+
* single layer, NOT `floating` above. This component follows seed, not
|
|
61
|
+
* Attio, for the same reason `DatePicker` follows seed's calendar
|
|
62
|
+
* structure: an explicit owner request to match seed-design exactly.
|
|
63
|
+
*/
|
|
64
|
+
readonly selectFloating: `0 4px 16px var(--${string})`;
|
|
58
65
|
};
|
|
59
66
|
export type ElevationKey = keyof typeof elevation;
|