@llumi/design-system 1.0.1 → 2.1.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.
Files changed (48) hide show
  1. package/LICENSE +51 -0
  2. package/NOTICE +66 -0
  3. package/README.md +15 -205
  4. package/adopt-global-styles-D9108lqB.js +15 -0
  5. package/base.css +2 -0
  6. package/base.md +59 -0
  7. package/bpmn.md +113 -0
  8. package/bpmn.mjs +5076 -0
  9. package/copy-button.md +128 -0
  10. package/copy-button.mjs +161 -0
  11. package/custom-elements.json +1135 -18
  12. package/download-button.md +106 -0
  13. package/download-button.mjs +177 -0
  14. package/highlighter.md +45 -0
  15. package/highlighter.mjs +403 -0
  16. package/icon-button-BwB11RGC.js +5 -0
  17. package/icons-BaUbjt-v.js +42 -0
  18. package/index-BEhA78nX.js +7733 -0
  19. package/llumi-element-BWRwgzW5.js +22 -0
  20. package/mermaid.md +58 -0
  21. package/mermaid.mjs +254 -0
  22. package/package.json +16 -50
  23. package/review.md +141 -0
  24. package/review.mjs +2044 -0
  25. package/slot-text-mSWBdWBc.js +51 -0
  26. package/theme.css +2 -0
  27. package/dist/review.cjs +0 -172
  28. package/dist/review.css +0 -98
  29. package/dist/review.js +0 -172
  30. package/dist/review.mjs +0 -1710
  31. package/dist/types/components/review/comment-dialog.element.d.ts +0 -29
  32. package/dist/types/components/review/custom-target.utils.d.ts +0 -16
  33. package/dist/types/components/review/default-editor.element.d.ts +0 -19
  34. package/dist/types/components/review/highlight-manager.d.ts +0 -21
  35. package/dist/types/components/review/index.d.ts +0 -8
  36. package/dist/types/components/review/overall-comment-dialog.element.d.ts +0 -22
  37. package/dist/types/components/review/review-bar.element.d.ts +0 -26
  38. package/dist/types/components/review/review.element.d.ts +0 -60
  39. package/dist/types/components/review/review.machine.d.ts +0 -234
  40. package/dist/types/components/review/review.persistence.d.ts +0 -16
  41. package/dist/types/components/review/review.type.d.ts +0 -37
  42. package/dist/types/components/review/selection-comment-icons.element.d.ts +0 -17
  43. package/dist/types/components/review/selection-range.utils.d.ts +0 -6
  44. package/dist/types/components/review/sort-comments.utils.d.ts +0 -6
  45. package/dist/types/index.d.ts +0 -1
  46. package/dist/types/shared/cn.d.ts +0 -2
  47. package/dist/types/shared/icons.d.ts +0 -7
  48. package/dist/types/shared/tailwind-element.d.ts +0 -4
package/copy-button.md ADDED
@@ -0,0 +1,128 @@
1
+ # `<llumi-copy-button>`
2
+
3
+ Copy-to-clipboard icon button with animated success/error feedback.
4
+
5
+ ## What it is
6
+
7
+ A minimal icon button that copies text to the clipboard and shows live state transitions:
8
+
9
+ | State | Visual |
10
+ |-------|--------|
11
+ | idle | copy icon |
12
+ | copying | spinning indicator (button disabled) |
13
+ | copied | green ✓ icon, resets after 1 s |
14
+ | error | red × icon, resets after 1 s |
15
+
16
+ ---
17
+
18
+ ## Usage
19
+
20
+ > **Requires the base theme.** This is a light-DOM element styled by the design-system stylesheet — load `@llumi/design-system/base.css` (or `base.css`) on the page, or the button renders unstyled.
21
+
22
+ ```html
23
+ <!-- 1. Register the element (auto side-effect) -->
24
+ <script type="module">
25
+ import "@llumi/design-system/copy-button";
26
+ </script>
27
+
28
+ <!-- 2. Drop the tag wherever you need it -->
29
+ <llumi-copy-button value="Text to copy"></llumi-copy-button>
30
+ ```
31
+
32
+ Or with named import:
33
+
34
+ ```js
35
+ import { LlumiCopyButton } from "@llumi/design-system/copy-button";
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Copy source precedence
41
+
42
+ The text that gets written to the clipboard is resolved from the first source that is available, in this order:
43
+
44
+ 1. **`getValue` (JS function property)** — highest precedence. Assign a function:
45
+ ```js
46
+ document.querySelector("llumi-copy-button").getValue = () => editor.getValue();
47
+ ```
48
+ 2. **`get-value` (attribute)** — a dotted path to a function on `globalThis`, resolved at click time via plain property traversal (no `eval`, no `new Function`). The component warns in the console if the path does not resolve to a function:
49
+ ```html
50
+ <llumi-copy-button get-value="myApp.getSnippet"></llumi-copy-button>
51
+ ```
52
+ ```js
53
+ window.myApp = { getSnippet: () => editor.getValue() };
54
+ ```
55
+ 3. **`value` (string attribute)** — a plain, static string:
56
+ ```html
57
+ <llumi-copy-button value="npm install @llumi/design-system"></llumi-copy-button>
58
+ ```
59
+ 4. **`""` (empty string)** — fallback when none of the above is set.
60
+
61
+ ---
62
+
63
+ ## Attributes and properties
64
+
65
+ | Name | Type | Default | Notes |
66
+ |------|------|---------|-------|
67
+ | `value` | `string` attr + prop | `""` | Static text to copy. Lowest-precedence source. |
68
+ | `title` | `string` attr + prop | `"Copy to clipboard"` | Native tooltip; mirrored to `aria-label`. |
69
+ | `getValue` | `() => string` prop only | `undefined` | JS function property. No HTML attribute equivalent. Highest-precedence source. |
70
+ | `get-value` | `string` attr | — | Dotted path on `globalThis` resolving to a function. Resolved at click time. |
71
+ | `disabled` | — | — | Managed internally while copying; do not set manually. |
72
+
73
+ ---
74
+
75
+ ## Events
76
+
77
+ Both events bubble and are composed.
78
+
79
+ ### `llumi-copy`
80
+
81
+ Fires on a successful clipboard write.
82
+
83
+ ```ts
84
+ element.addEventListener("llumi-copy", (e: CustomEvent<{ text: string }>) => {
85
+ console.log("Copied:", e.detail.text);
86
+ });
87
+ ```
88
+
89
+ ### `llumi-copy-error`
90
+
91
+ Fires when `navigator.clipboard.writeText` rejects (e.g. permission denied in a non-HTTPS context or missing user gesture).
92
+
93
+ ```ts
94
+ element.addEventListener("llumi-copy-error", (e: CustomEvent<{ error: unknown }>) => {
95
+ console.error("Copy failed:", e.detail.error);
96
+ });
97
+ ```
98
+
99
+ ---
100
+
101
+ ## Styling
102
+
103
+ ### Styling the button (light DOM)
104
+
105
+ The component renders in **light DOM**, so the inner `<button>` is a normal,
106
+ fully styleable element — no shadow piercing required:
107
+
108
+ ```css
109
+ llumi-copy-button button {
110
+ width: 3rem;
111
+ height: 3rem;
112
+ border-radius: 9999px;
113
+ }
114
+ ```
115
+
116
+ ### CSS custom properties
117
+
118
+ Each token has a sensible `oklch` fallback, so the component is usable without a design-system theme.
119
+
120
+ | Token | Role | Fallback |
121
+ |-------|------|---------|
122
+ | `--llumi-color-success` | Border + icon colour in the copied state | `oklch(62.7% 0.194 149.214)` (green) |
123
+ | `--llumi-color-danger` | Border + icon colour in the error state | `oklch(57.7% 0.245 27.325)` (red) |
124
+ | `--llumi-color-surface` | Button background | `oklch(100% 0 0)` (white) |
125
+ | `--llumi-color-border` | Button border | `oklch(92% 0.004 286.32)` (light grey) |
126
+ | `--llumi-color-fg` | Icon colour (idle) | `oklch(21% 0.006 285.885)` (near-black) |
127
+ | `--llumi-color-ring` | Focus-visible outline | `oklch(55.8% 0.288 302.321)` (purple) |
128
+ | `--llumi-radius` | Button border-radius | `0.5rem` |
@@ -0,0 +1,161 @@
1
+ import { html as d } from "https://cdn.jsdelivr.net/npm/lit@3.3.3";
2
+ import { property as u, customElement as h } from "https://cdn.jsdelivr.net/npm/lit@3.3.3/decorators.js";
3
+ import { i as s } from "./icons-BaUbjt-v.js";
4
+ import { L as b } from "./llumi-element-BWRwgzW5.js";
5
+ import { defineMachine as m } from "https://cdn.jsdelivr.net/npm/yay-machine@1.5.0";
6
+ /*! @llumi/design-system v2.1.0 | (c) 2026 pAIrprog SAS | license: https://cdn.jsdelivr.net/npm/@llumi/design-system@2.1.0/LICENSE | bundled third-party components under MIT, see NOTICE | @license */
7
+ const p = 1e3, f = m({
8
+ initialState: { name: "idle" },
9
+ states: {
10
+ idle: {
11
+ on: {
12
+ COPY: { to: "copying", data: ({ event: t }) => ({ text: t.text }) }
13
+ }
14
+ },
15
+ copying: {
16
+ onEnter: ({ state: t, send: e }) => {
17
+ navigator.clipboard.writeText(t.text).then(() => e({ type: "COPY_SUCCESS", text: t.text })).catch((o) => e({ type: "COPY_ERROR", error: o }));
18
+ },
19
+ on: {
20
+ COPY_SUCCESS: { to: "copied" },
21
+ COPY_ERROR: { to: "error" }
22
+ }
23
+ },
24
+ copied: {
25
+ onEnter: ({ send: t }) => {
26
+ const e = setTimeout(() => t({ type: "DONE" }), p);
27
+ return () => clearTimeout(e);
28
+ },
29
+ on: {
30
+ DONE: { to: "idle" },
31
+ COPY: { to: "copying", data: ({ event: t }) => ({ text: t.text }) }
32
+ }
33
+ },
34
+ error: {
35
+ onEnter: ({ send: t }) => {
36
+ const e = setTimeout(() => t({ type: "DONE" }), p);
37
+ return () => clearTimeout(e);
38
+ },
39
+ on: {
40
+ DONE: { to: "idle" },
41
+ COPY: { to: "copying", data: ({ event: t }) => ({ text: t.text }) }
42
+ }
43
+ }
44
+ }
45
+ });
46
+ function y(t, e = globalThis) {
47
+ let o = e;
48
+ for (const r of t.split(".")) {
49
+ if (o == null) return;
50
+ o = o[r];
51
+ }
52
+ return o;
53
+ }
54
+ var C = Object.defineProperty, E = Object.getOwnPropertyDescriptor, c = (t, e, o, r) => {
55
+ for (var i = r > 1 ? void 0 : r ? E(e, o) : e, l = t.length - 1, a; l >= 0; l--)
56
+ (a = t[l]) && (i = (r ? a(e, o, i) : a(i)) || i);
57
+ return r && i && C(e, o, i), i;
58
+ };
59
+ function O(t) {
60
+ throw new Error(`Unexpected state: ${JSON.stringify(t)}`);
61
+ }
62
+ let n = class extends b {
63
+ constructor() {
64
+ super(...arguments), this.value = "", this.title = "Copy to clipboard";
65
+ }
66
+ /** Light DOM so the document-level base.css button style applies. */
67
+ createRenderRoot() {
68
+ return this;
69
+ }
70
+ connectedCallback() {
71
+ super.connectedCallback(), this.instance = f.newInstance().start(), this.unsubscribe = this.instance.subscribe(
72
+ ({ state: t, event: e }) => this.onTransition(t, e)
73
+ );
74
+ }
75
+ disconnectedCallback() {
76
+ var t, e;
77
+ super.disconnectedCallback(), (t = this.unsubscribe) == null || t.call(this), this.unsubscribe = void 0, (e = this.instance) == null || e.stop(), this.instance = void 0;
78
+ }
79
+ onTransition(t, e) {
80
+ (e == null ? void 0 : e.type) === "COPY_SUCCESS" ? this.dispatchEvent(
81
+ new CustomEvent("llumi-copy", {
82
+ detail: { text: e.text },
83
+ bubbles: !0,
84
+ composed: !0
85
+ })
86
+ ) : (e == null ? void 0 : e.type) === "COPY_ERROR" && this.dispatchEvent(
87
+ new CustomEvent("llumi-copy-error", {
88
+ detail: { error: e.error },
89
+ bubbles: !0,
90
+ composed: !0
91
+ })
92
+ ), this.requestUpdate();
93
+ }
94
+ /**
95
+ * Resolve the text to copy, by precedence:
96
+ * getValue() (function prop)
97
+ * → get-value (attribute: dotted path to a function on globalThis, resolved at click time)
98
+ * → value (string attr)
99
+ * → ""
100
+ */
101
+ resolveText() {
102
+ if (typeof this.getValue == "function") return this.getValue();
103
+ const t = this.getAttribute("get-value");
104
+ if (t) {
105
+ const e = y(t);
106
+ if (typeof e == "function")
107
+ return String(e());
108
+ console.warn(
109
+ `<llumi-copy-button>: get-value="${t}" did not resolve to a function on globalThis`
110
+ );
111
+ }
112
+ return this.value ?? "";
113
+ }
114
+ onClick() {
115
+ var t;
116
+ (t = this.instance) == null || t.send({ type: "COPY", text: this.resolveText() });
117
+ }
118
+ viewFor(t) {
119
+ switch (t) {
120
+ case "idle":
121
+ return { icon: s.copy, cls: "" };
122
+ case "copying":
123
+ return { icon: s.spinner, cls: "is-working" };
124
+ case "copied":
125
+ return { icon: s.check, cls: "is-done" };
126
+ case "error":
127
+ return { icon: s.x, cls: "is-error" };
128
+ default:
129
+ return O(t);
130
+ }
131
+ }
132
+ render() {
133
+ var o;
134
+ const t = ((o = this.instance) == null ? void 0 : o.state.name) ?? "idle", e = this.viewFor(t);
135
+ return d`<button
136
+ type="button"
137
+ class=${e.cls}
138
+ title=${this.title}
139
+ aria-label=${this.title}
140
+ ?disabled=${t === "copying"}
141
+ @click=${this.onClick}
142
+ >
143
+ <i>${e.icon}</i>
144
+ </button>`;
145
+ }
146
+ };
147
+ c([
148
+ u()
149
+ ], n.prototype, "value", 2);
150
+ c([
151
+ u()
152
+ ], n.prototype, "title", 2);
153
+ c([
154
+ u({ attribute: !1 })
155
+ ], n.prototype, "getValue", 2);
156
+ n = c([
157
+ h("llumi-copy-button")
158
+ ], n);
159
+ export {
160
+ n as LlumiCopyButton
161
+ };