@camunda/design-system 0.33.0 → 0.34.0
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/carbon-compat/button.d.ts +3 -1
- package/dist/carbon-compat/button.d.ts.map +1 -1
- package/dist/carbon-compat/button.js.map +1 -1
- package/dist/carbon-compat/code-snippet.d.ts +17 -12
- package/dist/carbon-compat/code-snippet.d.ts.map +1 -1
- package/dist/carbon-compat/code-snippet.js +72 -24
- package/dist/carbon-compat/code-snippet.js.map +1 -1
- package/dist/carbon-compat/text-area.d.ts.map +1 -1
- package/dist/carbon-compat/text-area.js +6 -8
- package/dist/carbon-compat/text-area.js.map +1 -1
- package/dist/src/components/ui/button.d.ts +10 -0
- package/dist/src/components/ui/button.d.ts.map +1 -1
- package/dist/src/components/ui/button.js +33 -6
- package/dist/src/components/ui/button.js.map +1 -1
- package/dist/styles.css +21 -0
- package/package.json +1 -1
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import * as React from "react";
|
|
2
2
|
import type { ButtonProps as CarbonButtonProps } from "@carbon/react";
|
|
3
|
-
export type ButtonProps<T extends React.ElementType = "button"> = CarbonButtonProps<T
|
|
3
|
+
export type ButtonProps<T extends React.ElementType = "button"> = CarbonButtonProps<T> & {
|
|
4
|
+
loading?: boolean;
|
|
5
|
+
};
|
|
4
6
|
declare function Button(props: ButtonProps<"button">): React.JSX.Element;
|
|
5
7
|
export { Button };
|
|
6
8
|
//# sourceMappingURL=button.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../carbon-compat/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../carbon-compat/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,OAAO,KAAK,EAAE,WAAW,IAAI,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAGtE,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,KAAK,CAAC,WAAW,GAAG,QAAQ,IAC5D,iBAAiB,CAAC,CAAC,CAAC,GAAG;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAoC/C,iBAAS,MAAM,CAAC,KAAK,EAAE,WAAW,CAAC,QAAQ,CAAC,qBAmD3C;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../carbon-compat/button.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../carbon-compat/button.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAsBpD,MAAM,eAAe,GAAsC;IACzD,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE,WAAW;IACrB,KAAK,EAAE,OAAO;IACd,MAAM,EAAE,aAAa;IACrB,kBAAkB,EAAE,aAAa;IACjC,eAAe,EAAE,aAAa;CAC/B,CAAC;AAGF,MAAM,YAAY,GAAmC;IACnD,EAAE,EAAE,IAAI;IACR,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,IAAI;IACR,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,SAAS,MAAM,CAAC,KAA4B;IAC1C,MAAM,EACJ,IAAI,EACJ,IAAI,EACJ,UAAU,EAAE,UAAU,EACtB,eAAe,EACf,WAAW,EACX,YAAY,EACZ,UAAU,EACV,gBAAgB,EAChB,eAAe,EACf,EAAE,EACF,QAAQ,EACR,SAAS,EACT,GAAG,IAAI,EACR,GAAG,KAaH,CAAC;IACF,gBAAgB,CAAC,QAAQ,EAAE;QACzB,eAAe;QACf,WAAW;QACX,YAAY;QACZ,UAAU;QACV,gBAAgB;QAChB,eAAe;QACf,EAAE;KACH,CAAC,CAAC;IACH,MAAM,OAAO,GAAkB,IAAI,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACxE,MAAM,UAAU,GAAe,IAAI,CAAC,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrE,OAAO,CACL,MAAC,YAAY,IACX,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,UAAU,EAChB,SAAS,EAAE,SAAS,KACf,IAAkD,aAEtD,UAAU,CAAC,CAAC,CAAC,KAAC,UAAU,KAAG,CAAC,CAAC,CAAC,IAAI,EAClC,QAAQ,IACI,CAChB,CAAC;AACJ,CAAC;AAED,OAAO,EAAE,MAAM,EAAE,CAAC"}
|
|
@@ -1,28 +1,33 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from "react";
|
|
2
2
|
import type { CodeSnippetProps as CarbonCodeSnippetProps } from "@carbon/react";
|
|
3
3
|
export type CodeSnippetProps = CarbonCodeSnippetProps & {
|
|
4
4
|
children?: React.ReactNode;
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
7
|
* CodeSnippet — Carbon-shaped adapter that renders code with Tailwind
|
|
8
|
-
* + mono font.
|
|
8
|
+
* + mono font and a copy affordance.
|
|
9
9
|
*
|
|
10
10
|
* Maps:
|
|
11
11
|
* type: 'inline' → inline `<code>` with subtle background
|
|
12
12
|
* type: 'single' | 'multi' → block `<pre><code>` with horizontal/
|
|
13
13
|
* vertical overflow as appropriate
|
|
14
14
|
* children → rendered as the code text
|
|
15
|
+
* copy button (block form) → composes a small DS `<Button>`:
|
|
16
|
+
* - copies `copyText ?? <rendered code text>` to the clipboard
|
|
17
|
+
* (matches Carbon's `handleCopyClick`),
|
|
18
|
+
* - then calls `onClick`,
|
|
19
|
+
* - swaps to a checkmark and announces `feedback` (default
|
|
20
|
+
* "Copied!") for `feedbackTimeout` ms (default 2000),
|
|
21
|
+
* - suppressed by `hideCopyButton`,
|
|
22
|
+
* - labelled by `copyButtonDescription` / `aria-label`
|
|
23
|
+
* (default "Copy to clipboard").
|
|
15
24
|
*
|
|
16
|
-
* Drops (with dev warning) — Carbon affordances
|
|
17
|
-
* align, autoAlign,
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* The copy-button affordance is a meaningful piece consumers may rely
|
|
24
|
-
* on; if needed, we add it as a follow-up that composes a small
|
|
25
|
-
* `<Button>` next to the code block.
|
|
25
|
+
* Drops (with dev warning) — Carbon affordances not modelled here:
|
|
26
|
+
* align, autoAlign, maxCollapsedNumberOfRows, maxExpandedNumberOfRows,
|
|
27
|
+
* minCollapsedNumberOfRows, minExpandedNumberOfRows, showLessText,
|
|
28
|
+
* showMoreText, wrapText, light, decorator, slug. Inline snippets are
|
|
29
|
+
* static (no copy button) — Carbon's click-to-copy inline behaviour is
|
|
30
|
+
* not modelled.
|
|
26
31
|
*/
|
|
27
32
|
declare function CodeSnippet({ type, disabled, className, children, ...rest }: CodeSnippetProps): React.JSX.Element;
|
|
28
33
|
export { CodeSnippet };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-snippet.d.ts","sourceRoot":"","sources":["../../carbon-compat/code-snippet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,
|
|
1
|
+
{"version":3,"file":"code-snippet.d.ts","sourceRoot":"","sources":["../../carbon-compat/code-snippet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,KAAK,EAAE,gBAAgB,IAAI,sBAAsB,EAAE,MAAM,eAAe,CAAC;AAShF,MAAM,MAAM,gBAAgB,GAAG,sBAAsB,GAAG;IACtD,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CAC5B,CAAC;AAMF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,iBAAS,WAAW,CAAC,EACnB,IAAe,EACf,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,GAAG,IAAI,EACR,EAAE,gBAAgB,qBAgKlB;AAED,OAAO,EAAE,WAAW,EAAE,CAAC"}
|
|
@@ -1,43 +1,46 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import { Check, Copy } from "lucide-react";
|
|
4
|
+
import { Button } from "../src/components/ui/button.js";
|
|
2
5
|
import { cn, warnDroppedProps } from "../src/lib/utils.js";
|
|
6
|
+
const DEFAULT_FEEDBACK = "Copied!";
|
|
7
|
+
const DEFAULT_FEEDBACK_TIMEOUT = 2000;
|
|
8
|
+
const DEFAULT_COPY_LABEL = "Copy to clipboard";
|
|
3
9
|
/**
|
|
4
10
|
* CodeSnippet — Carbon-shaped adapter that renders code with Tailwind
|
|
5
|
-
* + mono font.
|
|
11
|
+
* + mono font and a copy affordance.
|
|
6
12
|
*
|
|
7
13
|
* Maps:
|
|
8
14
|
* type: 'inline' → inline `<code>` with subtle background
|
|
9
15
|
* type: 'single' | 'multi' → block `<pre><code>` with horizontal/
|
|
10
16
|
* vertical overflow as appropriate
|
|
11
17
|
* children → rendered as the code text
|
|
18
|
+
* copy button (block form) → composes a small DS `<Button>`:
|
|
19
|
+
* - copies `copyText ?? <rendered code text>` to the clipboard
|
|
20
|
+
* (matches Carbon's `handleCopyClick`),
|
|
21
|
+
* - then calls `onClick`,
|
|
22
|
+
* - swaps to a checkmark and announces `feedback` (default
|
|
23
|
+
* "Copied!") for `feedbackTimeout` ms (default 2000),
|
|
24
|
+
* - suppressed by `hideCopyButton`,
|
|
25
|
+
* - labelled by `copyButtonDescription` / `aria-label`
|
|
26
|
+
* (default "Copy to clipboard").
|
|
12
27
|
*
|
|
13
|
-
* Drops (with dev warning) — Carbon affordances
|
|
14
|
-
* align, autoAlign,
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* The copy-button affordance is a meaningful piece consumers may rely
|
|
21
|
-
* on; if needed, we add it as a follow-up that composes a small
|
|
22
|
-
* `<Button>` next to the code block.
|
|
28
|
+
* Drops (with dev warning) — Carbon affordances not modelled here:
|
|
29
|
+
* align, autoAlign, maxCollapsedNumberOfRows, maxExpandedNumberOfRows,
|
|
30
|
+
* minCollapsedNumberOfRows, minExpandedNumberOfRows, showLessText,
|
|
31
|
+
* showMoreText, wrapText, light, decorator, slug. Inline snippets are
|
|
32
|
+
* static (no copy button) — Carbon's click-to-copy inline behaviour is
|
|
33
|
+
* not modelled.
|
|
23
34
|
*/
|
|
24
35
|
function CodeSnippet({ type = "single", disabled, className, children, ...rest }) {
|
|
25
|
-
|
|
26
|
-
// flow onto the DOM as unknown attributes.
|
|
27
|
-
const { align, autoAlign, copyButtonDescription, copyText, feedback, feedbackTimeout, hideCopyButton, maxCollapsedNumberOfRows, maxExpandedNumberOfRows, minCollapsedNumberOfRows, minExpandedNumberOfRows, onClick, showLessText, showMoreText, wrapText, light, decorator, slug, ariaLabel, ...domRest } = rest;
|
|
36
|
+
const { align, autoAlign, copyButtonDescription, copyText, feedback, feedbackTimeout, hideCopyButton, maxCollapsedNumberOfRows, maxExpandedNumberOfRows, minCollapsedNumberOfRows, minExpandedNumberOfRows, onClick, showLessText, showMoreText, wrapText, light, decorator, slug, ["aria-label"]: ariaLabel, ariaLabel: deprecatedAriaLabel, ...domRest } = rest;
|
|
28
37
|
warnDroppedProps("CodeSnippet", {
|
|
29
38
|
align,
|
|
30
39
|
autoAlign,
|
|
31
|
-
copyButtonDescription,
|
|
32
|
-
copyText,
|
|
33
|
-
feedback,
|
|
34
|
-
feedbackTimeout,
|
|
35
|
-
hideCopyButton,
|
|
36
40
|
maxCollapsedNumberOfRows,
|
|
37
41
|
maxExpandedNumberOfRows,
|
|
38
42
|
minCollapsedNumberOfRows,
|
|
39
43
|
minExpandedNumberOfRows,
|
|
40
|
-
onClick,
|
|
41
44
|
showLessText,
|
|
42
45
|
showMoreText,
|
|
43
46
|
wrapText,
|
|
@@ -45,11 +48,56 @@ function CodeSnippet({ type = "single", disabled, className, children, ...rest }
|
|
|
45
48
|
decorator,
|
|
46
49
|
slug,
|
|
47
50
|
});
|
|
51
|
+
const codeRef = React.useRef(null);
|
|
52
|
+
const [copied, setCopied] = React.useState(false);
|
|
53
|
+
const resetTimerRef = React.useRef(undefined);
|
|
54
|
+
React.useEffect(() => () => clearTimeout(resetTimerRef.current), []);
|
|
55
|
+
const copyLabel = typeof copyButtonDescription === "string"
|
|
56
|
+
? copyButtonDescription
|
|
57
|
+
: typeof ariaLabel === "string"
|
|
58
|
+
? ariaLabel
|
|
59
|
+
: typeof deprecatedAriaLabel === "string"
|
|
60
|
+
? deprecatedAriaLabel
|
|
61
|
+
: DEFAULT_COPY_LABEL;
|
|
62
|
+
const feedbackLabel = typeof feedback === "string" ? feedback : DEFAULT_FEEDBACK;
|
|
63
|
+
const timeout = typeof feedbackTimeout === "number"
|
|
64
|
+
? feedbackTimeout
|
|
65
|
+
: DEFAULT_FEEDBACK_TIMEOUT;
|
|
66
|
+
const handleCopy = (event) => {
|
|
67
|
+
const text = typeof copyText === "string"
|
|
68
|
+
? copyText
|
|
69
|
+
: (codeRef.current?.textContent ?? "");
|
|
70
|
+
if (text) {
|
|
71
|
+
// Swallow rejections (writeText rejects when the document isn't focused or
|
|
72
|
+
// permission is denied); onClick + feedback still fire regardless.
|
|
73
|
+
void navigator.clipboard?.writeText(text)?.catch(() => { });
|
|
74
|
+
}
|
|
75
|
+
onClick?.(event);
|
|
76
|
+
setCopied(true);
|
|
77
|
+
clearTimeout(resetTimerRef.current);
|
|
78
|
+
resetTimerRef.current = setTimeout(() => setCopied(false), timeout);
|
|
79
|
+
};
|
|
48
80
|
if (type === "inline") {
|
|
49
|
-
|
|
81
|
+
// Inline snippets are static — Carbon's click-to-copy inline behaviour is not
|
|
82
|
+
// modelled, so surface the copy-related props as dropped (they're only honoured
|
|
83
|
+
// in the block form above).
|
|
84
|
+
warnDroppedProps("CodeSnippet (inline)", {
|
|
85
|
+
onClick,
|
|
86
|
+
copyText,
|
|
87
|
+
feedback,
|
|
88
|
+
feedbackTimeout,
|
|
89
|
+
hideCopyButton,
|
|
90
|
+
copyButtonDescription,
|
|
91
|
+
});
|
|
92
|
+
return (_jsx("code", { ref: codeRef, "data-slot": "carbon-compat-code-snippet", "data-type": "inline", "aria-label": typeof ariaLabel === "string" ? ariaLabel : undefined, className: cn("rounded bg-neutral-background-strong px-1.5 py-0.5 font-mono text-xs", disabled && "opacity-50", className), ...domRest, children: children }));
|
|
50
93
|
}
|
|
51
|
-
// block form (`single` or `multi`)
|
|
52
|
-
|
|
94
|
+
// block form (`single` or `multi`). The bare wrapper is a non-scrolling
|
|
95
|
+
// positioning context for the copy button — identity (`data-slot`/`data-type`),
|
|
96
|
+
// consumer `className`, and pass-through DOM props stay on the `<pre>` (the
|
|
97
|
+
// scroll container) so the adapter's DOM contract matches the pre-copy-button
|
|
98
|
+
// version. The button lives on the wrapper (not inside the `<pre>`) so it stays
|
|
99
|
+
// fixed while long code scrolls horizontally.
|
|
100
|
+
return (_jsxs("div", { className: "relative", children: [_jsx("pre", { "data-slot": "carbon-compat-code-snippet", "data-type": type, className: cn("overflow-x-auto rounded bg-neutral-background-strong p-3 font-mono text-xs", type === "multi" && "whitespace-pre", !hideCopyButton && "pr-10", disabled && "opacity-50", className), ...domRest, children: _jsx("code", { ref: codeRef, children: children }) }), !hideCopyButton && (_jsx(Button, { type: "button", variant: "ghost", size: "icon-xs", disabled: disabled, onClick: handleCopy, "aria-label": copied ? feedbackLabel : copyLabel, title: copied ? feedbackLabel : copyLabel, className: "absolute top-1.5 right-1.5", children: copied ? (_jsx(Check, { className: "size-3.5 text-success-action-default", "aria-hidden": "true" })) : (_jsx(Copy, { className: "size-3.5", "aria-hidden": "true" })) })), _jsx("span", { role: "status", "aria-live": "polite", className: "sr-only", children: copied ? feedbackLabel : "" })] }));
|
|
53
101
|
}
|
|
54
102
|
export { CodeSnippet };
|
|
55
103
|
//# sourceMappingURL=code-snippet.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"code-snippet.js","sourceRoot":"","sources":["../../carbon-compat/code-snippet.tsx"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"code-snippet.js","sourceRoot":"","sources":["../../carbon-compat/code-snippet.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-area.d.ts","sourceRoot":"","sources":["../../carbon-compat/text-area.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,aAAa,IAAI,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE1E,MAAM,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAEhD,iBAAS,QAAQ,CAAC,KAAK,EAAE,aAAa,
|
|
1
|
+
{"version":3,"file":"text-area.d.ts","sourceRoot":"","sources":["../../carbon-compat/text-area.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,OAAO,KAAK,EAAE,aAAa,IAAI,mBAAmB,EAAE,MAAM,eAAe,CAAC;AAE1E,MAAM,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAEhD,iBAAS,QAAQ,CAAC,KAAK,EAAE,aAAa,qBA4IrC;AAED,OAAO,EAAE,QAAQ,EAAE,CAAC"}
|
|
@@ -6,15 +6,13 @@ import { cn, warnDroppedProps } from "../src/lib/utils.js";
|
|
|
6
6
|
function TextArea(props) {
|
|
7
7
|
const { id, labelText, helperText, invalid, invalidText, warn, warnText, enableCounter, maxCount, counterMode, hideLabel, light, className, disabled, placeholder, value, defaultValue, onChange, onBlur, onFocus, rows, cols, readOnly, ...rest } = props;
|
|
8
8
|
warnDroppedProps("TextArea", {
|
|
9
|
-
helperText,
|
|
10
|
-
invalid,
|
|
11
|
-
invalidText,
|
|
12
9
|
warn,
|
|
13
10
|
warnText,
|
|
14
11
|
hideLabel,
|
|
15
12
|
light,
|
|
16
13
|
});
|
|
17
14
|
const showCounter = enableCounter && maxCount !== undefined;
|
|
15
|
+
const message = invalid && invalidText !== undefined ? (_jsx("span", { className: "text-xs text-danger-action-default", children: invalidText })) : !invalid && helperText !== undefined ? (_jsx("span", { className: "text-xs text-neutral-foreground-subtle", children: helperText })) : null;
|
|
18
16
|
const isControlled = value !== undefined;
|
|
19
17
|
const [uncontrolledValue, setUncontrolledValue] = React.useState(() => String(defaultValue ?? ""));
|
|
20
18
|
const liveValue = isControlled ? String(value) : uncontrolledValue;
|
|
@@ -23,18 +21,18 @@ function TextArea(props) {
|
|
|
23
21
|
setUncontrolledValue(event.target.value);
|
|
24
22
|
onChange?.(event);
|
|
25
23
|
};
|
|
26
|
-
const wrapped = labelText !== undefined || showCounter;
|
|
24
|
+
const wrapped = labelText !== undefined || showCounter || message !== null;
|
|
27
25
|
const counterId = showCounter && id ? `${id}-counter` : undefined;
|
|
28
26
|
// Carbon auto-caps character-mode counters via native `maxLength`; word mode
|
|
29
27
|
// has no native equivalent and is left uncapped, matching Carbon's own behavior.
|
|
30
28
|
const nativeMaxLength = showCounter && counterMode !== "word" ? maxCount : undefined;
|
|
31
|
-
const textarea = (_jsx(Textarea, { id: id, className: wrapped ? undefined : className, disabled: disabled, placeholder: placeholder, value: value, defaultValue: defaultValue, onChange: handleChange, onBlur: onBlur, onFocus: onFocus, rows: rows, cols: cols, readOnly: readOnly, maxLength: nativeMaxLength, "aria-describedby": counterId, ...rest }));
|
|
29
|
+
const textarea = (_jsx(Textarea, { id: id, className: wrapped ? undefined : className, disabled: disabled, placeholder: placeholder, value: value, defaultValue: defaultValue, onChange: handleChange, onBlur: onBlur, onFocus: onFocus, rows: rows, cols: cols, readOnly: readOnly, maxLength: nativeMaxLength, "aria-invalid": invalid || undefined, "aria-describedby": counterId, ...rest }));
|
|
32
30
|
const counter = showCounter ? (_jsx(CharacterCount, { id: counterId, value: liveValue, max: maxCount, mode: counterMode === "word" ? "word" : "character", className: "self-end" })) : null;
|
|
33
31
|
if (labelText !== undefined) {
|
|
34
|
-
return (_jsxs("label", { htmlFor: id, className:
|
|
32
|
+
return (_jsxs("div", { className: cn("flex flex-col gap-2", className), children: [_jsxs("label", { htmlFor: id, className: "flex flex-col gap-2 text-sm", children: [_jsx("span", { children: labelText }), textarea] }), message, counter] }));
|
|
35
33
|
}
|
|
36
|
-
if (counter) {
|
|
37
|
-
return (_jsxs("div", { className: cn("flex flex-col gap-1", className), children: [textarea, counter] }));
|
|
34
|
+
if (counter || message) {
|
|
35
|
+
return (_jsxs("div", { className: cn("flex flex-col gap-1", className), children: [textarea, message, counter] }));
|
|
38
36
|
}
|
|
39
37
|
return textarea;
|
|
40
38
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text-area.js","sourceRoot":"","sources":["../../carbon-compat/text-area.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,cAAc,EAAE,MAAM,sCAAsC,CAAC;AACtE,OAAO,EAAE,QAAQ,EAAE,MAAM,+BAA+B,CAAC;AACzD,OAAO,EAAE,EAAE,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAKxD,SAAS,QAAQ,CAAC,KAAoB;IACpC,MAAM,EACJ,EAAE,EACF,SAAS,EACT,UAAU,EACV,OAAO,EACP,WAAW,EACX,IAAI,EACJ,QAAQ,EACR,aAAa,EACb,QAAQ,EACR,WAAW,EACX,SAAS,EACT,KAAK,EACL,SAAS,EACT,QAAQ,EACR,WAAW,EACX,KAAK,EACL,YAAY,EACZ,QAAQ,EACR,MAAM,EACN,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,GAAG,IAAI,EACR,GAAG,KAwBH,CAAC;IACF,gBAAgB,CAAC,UAAU,EAAE;QAC3B,
|
|
1
|
+
{"version":3,"file":"text-area.js","sourceRoot":"","sources":["../../carbon-compat/text-area.tsx"],"names":[],"mappings":"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"}
|
|
@@ -6,6 +6,16 @@ declare const buttonVariants: (props?: ({
|
|
|
6
6
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
7
|
type ButtonProps = React.ComponentProps<"button"> & VariantProps<typeof buttonVariants> & {
|
|
8
8
|
asChild?: boolean;
|
|
9
|
+
/**
|
|
10
|
+
* Shows an animated spinner in place of the leading icon (or before the
|
|
11
|
+
* label when there is no icon), sets `aria-busy="true"` and
|
|
12
|
+
* `aria-disabled="true"`, and ignores clicks so the action can't be
|
|
13
|
+
* double-submitted. Uses `aria-disabled` rather than the native
|
|
14
|
+
* `disabled` attribute so the button stays focusable and reachable by
|
|
15
|
+
* screen readers while busy. The label and the accessible name stay
|
|
16
|
+
* unchanged.
|
|
17
|
+
*/
|
|
18
|
+
loading?: boolean;
|
|
9
19
|
};
|
|
10
20
|
declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLButtonElement>>;
|
|
11
21
|
export { Button, buttonVariants };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;
|
|
1
|
+
{"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../src/components/ui/button.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAO,KAAK,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAOlE,QAAA,MAAM,cAAc;;;8EAiCnB,CAAC;AAEF,KAAK,WAAW,GAAG,KAAK,CAAC,cAAc,CAAC,QAAQ,CAAC,GAC/C,YAAY,CAAC,OAAO,cAAc,CAAC,GAAG;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAmFJ,QAAA,MAAM,MAAM,oGAAsD,CAAC;AAEnE,OAAO,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC"}
|
|
@@ -1,16 +1,17 @@
|
|
|
1
|
-
import { jsx as _jsx } from "react/jsx-runtime";
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { cva } from "class-variance-authority";
|
|
4
|
+
import { Loader2 } from "lucide-react";
|
|
4
5
|
import { Slot } from "radix-ui";
|
|
5
6
|
import { cn } from "../../lib/utils.js";
|
|
6
7
|
import { withRef } from "../../lib/with-ref.js";
|
|
7
|
-
const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:ring-3 focus-visible:ring-ring data-[focus-visible-restore]:ring-3 data-[focus-visible-restore]:ring-ring active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-danger-action-default aria-invalid:ring-3 aria-invalid:ring-danger-action-default/20 dark:aria-invalid:border-danger-action-default/50 dark:aria-invalid:ring-danger-action-default/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
8
|
+
const buttonVariants = cva("group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:ring-3 focus-visible:ring-ring data-[focus-visible-restore]:ring-3 data-[focus-visible-restore]:ring-ring active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-disabled:pointer-events-none aria-disabled:opacity-50 aria-invalid:border-danger-action-default aria-invalid:ring-3 aria-invalid:ring-danger-action-default/20 dark:aria-invalid:border-danger-action-default/50 dark:aria-invalid:ring-danger-action-default/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4", {
|
|
8
9
|
variants: {
|
|
9
10
|
variant: {
|
|
10
|
-
default: "bg-primary-action-default text-primary-action-foreground hover:bg-primary-action-hover active:bg-primary-action-active disabled:bg-primary-action-disabled",
|
|
11
|
+
default: "bg-primary-action-default text-primary-action-foreground hover:bg-primary-action-hover active:bg-primary-action-active disabled:bg-primary-action-disabled aria-disabled:bg-primary-action-disabled",
|
|
11
12
|
secondary: "border-input bg-neutral-background-subtle text-neutral-foreground-strong hover:bg-neutral-background-medium active:bg-neutral-background-strong aria-expanded:bg-neutral-background-medium aria-expanded:text-neutral-foreground-strong dark:hover:bg-neutral-background-medium dark:active:bg-neutral-background-strong dark:aria-expanded:bg-neutral-background-medium",
|
|
12
13
|
ghost: "text-neutral-foreground-subtle hover:bg-neutral-background-medium hover:text-neutral-foreground-strong active:bg-neutral-background-strong aria-expanded:bg-neutral-background-medium aria-expanded:text-neutral-foreground-strong dark:hover:bg-neutral-background-medium dark:active:bg-neutral-background-strong dark:aria-expanded:bg-neutral-background-medium",
|
|
13
|
-
destructive: "bg-danger-action-default text-danger-action-foreground hover:bg-danger-action-hover active:bg-danger-action-active disabled:bg-danger-action-disabled focus-visible:border-danger-border-subtle focus-visible:ring-danger-action-default/20 dark:focus-visible:ring-danger-action-default/40",
|
|
14
|
+
destructive: "bg-danger-action-default text-danger-action-foreground hover:bg-danger-action-hover active:bg-danger-action-active disabled:bg-danger-action-disabled aria-disabled:bg-danger-action-disabled focus-visible:border-danger-border-subtle focus-visible:ring-danger-action-default/20 dark:focus-visible:ring-danger-action-default/40",
|
|
14
15
|
link: "text-info-action-default underline-offset-4 hover:underline",
|
|
15
16
|
},
|
|
16
17
|
size: {
|
|
@@ -29,7 +30,7 @@ const buttonVariants = cva("group/button inline-flex shrink-0 items-center justi
|
|
|
29
30
|
size: "default",
|
|
30
31
|
},
|
|
31
32
|
});
|
|
32
|
-
function ButtonImpl({ ref, className, variant = "default", size = "default", asChild = false, type, ...props }) {
|
|
33
|
+
function ButtonImpl({ ref, className, variant = "default", size = "default", asChild = false, loading = false, disabled, type, children, onClick, "aria-busy": ariaBusy, "aria-disabled": ariaDisabled, ...props }) {
|
|
33
34
|
const Comp = asChild ? Slot.Root : "button";
|
|
34
35
|
// Default native <button> to type="button" so it never triggers an
|
|
35
36
|
// accidental form submit when placed inside a <form> (Dialog, Popover,
|
|
@@ -37,7 +38,33 @@ function ButtonImpl({ ref, className, variant = "default", size = "default", asC
|
|
|
37
38
|
// element may not be a <button>, and forcing `type` on a non-button would
|
|
38
39
|
// be invalid HTML.
|
|
39
40
|
const resolvedType = asChild ? type : (type ?? "button");
|
|
40
|
-
|
|
41
|
+
// Loading semantics apply to the native <button> only. `asChild` renders a
|
|
42
|
+
// Radix Slot, which requires exactly one child — injecting a spinner sibling
|
|
43
|
+
// would break `React.Children.only` — and may forward to a non-button
|
|
44
|
+
// element (e.g. <a>) that cannot be `disabled`.
|
|
45
|
+
const isLoading = loading && !asChild;
|
|
46
|
+
// Keep a single child so `asChild` (Radix Slot → React.Children.only) never
|
|
47
|
+
// sees an array. When loading, wrap the spinner + label in one fragment;
|
|
48
|
+
// display:contents keeps the button's flex/gap intact while
|
|
49
|
+
// `[&>svg:first-child]:hidden` hides the original leading icon (already
|
|
50
|
+
// aria-hidden, so the accessible name is untouched). No-op for text-only
|
|
51
|
+
// children; collapses an icon-only button to just the spinner.
|
|
52
|
+
const content = isLoading ? (_jsxs(_Fragment, { children: [_jsx(Loader2, { "aria-hidden": "true", "data-icon": "inline-start", className: "animate-spin" }), _jsx("span", { className: "contents [&>svg:first-child]:hidden", children: children })] })) : (children);
|
|
53
|
+
// `aria-disabled` (not native `disabled`) while loading: native `disabled`
|
|
54
|
+
// pulls the button out of the tab order and, in some browsers, the
|
|
55
|
+
// accessibility tree — a screen reader user could lose focus entirely and
|
|
56
|
+
// never hear the busy state. Staying focusable means the click itself must
|
|
57
|
+
// be blocked in JS instead of by the browser; `preventDefault` also covers
|
|
58
|
+
// `type="submit"` buttons, which would otherwise submit the form with no
|
|
59
|
+
// handler involved at all.
|
|
60
|
+
const handleClick = (event) => {
|
|
61
|
+
if (isLoading) {
|
|
62
|
+
event.preventDefault();
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
onClick?.(event);
|
|
66
|
+
};
|
|
67
|
+
return (_jsx(Comp, { ref: ref, type: resolvedType, "data-slot": "button", "data-variant": variant, "data-size": size, className: cn(buttonVariants({ variant, size, className })), ...props, disabled: disabled, "aria-busy": isLoading || ariaBusy, "aria-disabled": isLoading || ariaDisabled, onClick: handleClick, children: content }));
|
|
41
68
|
}
|
|
42
69
|
const Button = withRef(ButtonImpl);
|
|
43
70
|
export { Button, buttonVariants };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../src/components/ui/button.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,GAAG,EAAqB,MAAM,0BAA0B,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,UAAU,CAAC;AAEhC,OAAO,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,MAAM,cAAc,GAAG,GAAG,CACxB,
|
|
1
|
+
{"version":3,"file":"button.js","sourceRoot":"","sources":["../../../../src/components/ui/button.tsx"],"names":[],"mappings":"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"}
|
package/dist/styles.css
CHANGED
|
@@ -185,6 +185,9 @@
|
|
|
185
185
|
.top-0 {
|
|
186
186
|
top: 0px;
|
|
187
187
|
}
|
|
188
|
+
.top-1\.5 {
|
|
189
|
+
top: calc(var(--spacing) * 1.5);
|
|
190
|
+
}
|
|
188
191
|
.top-1\/2 {
|
|
189
192
|
top: calc(1 / 2 * 100%);
|
|
190
193
|
}
|
|
@@ -203,6 +206,9 @@
|
|
|
203
206
|
.right-0 {
|
|
204
207
|
right: 0px;
|
|
205
208
|
}
|
|
209
|
+
.right-1\.5 {
|
|
210
|
+
right: calc(var(--spacing) * 1.5);
|
|
211
|
+
}
|
|
206
212
|
.right-2 {
|
|
207
213
|
right: calc(var(--spacing) * 2);
|
|
208
214
|
}
|
|
@@ -1795,6 +1801,9 @@
|
|
|
1795
1801
|
.pr-9 {
|
|
1796
1802
|
padding-right: calc(var(--spacing) * 9);
|
|
1797
1803
|
}
|
|
1804
|
+
.pr-10 {
|
|
1805
|
+
padding-right: calc(var(--spacing) * 10);
|
|
1806
|
+
}
|
|
1798
1807
|
.pb-0 {
|
|
1799
1808
|
padding-bottom: 0px;
|
|
1800
1809
|
}
|
|
@@ -2812,6 +2821,15 @@
|
|
|
2812
2821
|
.aria-disabled\:cursor-default[aria-disabled="true"] {
|
|
2813
2822
|
cursor: default;
|
|
2814
2823
|
}
|
|
2824
|
+
.aria-disabled\:bg-danger-action-disabled[aria-disabled="true"] {
|
|
2825
|
+
background-color: var(--danger-action-disabled);
|
|
2826
|
+
}
|
|
2827
|
+
.aria-disabled\:bg-primary-action-disabled[aria-disabled="true"] {
|
|
2828
|
+
background-color: var(--primary-action-disabled);
|
|
2829
|
+
}
|
|
2830
|
+
.aria-disabled\:opacity-50[aria-disabled="true"] {
|
|
2831
|
+
opacity: 50%;
|
|
2832
|
+
}
|
|
2815
2833
|
.aria-expanded\:bg-neutral-background-medium[aria-expanded="true"] {
|
|
2816
2834
|
background-color: var(--neutral-background-medium);
|
|
2817
2835
|
}
|
|
@@ -3476,6 +3494,9 @@
|
|
|
3476
3494
|
.\[\&\>svg\]\:text-neutral-foreground-subtle > svg {
|
|
3477
3495
|
color: var(--neutral-foreground-subtle);
|
|
3478
3496
|
}
|
|
3497
|
+
.\[\&\>svg\:first-child\]\:hidden > svg:first-child {
|
|
3498
|
+
display: none;
|
|
3499
|
+
}
|
|
3479
3500
|
.\[\&\>tr\]\:last\:border-b-0 > tr:last-child {
|
|
3480
3501
|
border-bottom-style: var(--tw-border-style);
|
|
3481
3502
|
border-bottom-width: 0px;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@camunda/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.34.0",
|
|
4
4
|
"description": "Camunda's AI-first design system. shadcn + Tailwind components, design tokens aligned to Camunda's identity, and AI tooling for component authoring + migration.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|