@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
@@ -0,0 +1,106 @@
1
+ # `<llumi-download-button>`
2
+
3
+ Download-a-string-as-a-file icon button with animated success/error feedback.
4
+
5
+ ## What it is
6
+
7
+ A minimal icon button that downloads a string as a file and shows live state:
8
+
9
+ | State | Visual |
10
+ |-------|--------|
11
+ | idle | download icon |
12
+ | downloading | spinning indicator (button disabled) |
13
+ | downloaded | 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
+ <script type="module">
24
+ import "@llumi/design-system/download-button";
25
+ </script>
26
+
27
+ <llumi-download-button filename="data.json" mime-type="application/json"></llumi-download-button>
28
+ ```
29
+
30
+ Set the content via the `getValue` function property (Lit binding `.getValue=${…}`,
31
+ or assign it in JS):
32
+
33
+ ```js
34
+ const btn = document.querySelector("llumi-download-button");
35
+ btn.getValue = () => JSON.stringify(state, null, 2);
36
+ ```
37
+
38
+ ---
39
+
40
+ ## Attributes and properties
41
+
42
+ | Name | Type | Default | Notes |
43
+ |------|------|---------|-------|
44
+ | `getValue` | `() => string` prop only | `undefined` | Returns the content to download. Called at click time. No HTML attribute. |
45
+ | `filename` | `string` attr + prop | `""` | **Required.** A click with no filename logs a `console.warn` and does nothing. |
46
+ | `mime-type` | `string` attr (prop `mimeType`) | `"text/plain"` | MIME type passed to the `Blob`. |
47
+ | `title` | `string` attr + prop | `"Download file"` | Native tooltip; mirrored to `aria-label`. |
48
+ | `disabled` | — | — | Managed internally while downloading; do not set manually. |
49
+
50
+ ---
51
+
52
+ ## Events
53
+
54
+ Both events bubble and are composed.
55
+
56
+ ### `llumi-download`
57
+
58
+ Fires after the file download is triggered.
59
+
60
+ ```ts
61
+ element.addEventListener("llumi-download", (e: CustomEvent<{ filename: string }>) => {
62
+ console.log("Downloaded:", e.detail.filename);
63
+ });
64
+ ```
65
+
66
+ ### `llumi-download-error`
67
+
68
+ Fires if building or triggering the download throws.
69
+
70
+ ```ts
71
+ element.addEventListener("llumi-download-error", (e: CustomEvent<{ error: unknown }>) => {
72
+ console.error("Download failed:", e.detail.error);
73
+ });
74
+ ```
75
+
76
+ ---
77
+
78
+ ## Styling
79
+
80
+ The component renders in **light DOM**, so style the inner `<button>` directly —
81
+ no shadow piercing required:
82
+
83
+ ```css
84
+ llumi-download-button button {
85
+ width: 3rem;
86
+ height: 3rem;
87
+ border-radius: 9999px;
88
+ }
89
+ ```
90
+
91
+ The shared icon-button look (and `.is-done` / `.is-error` state colours) is defined
92
+ once in `base.css` and shared with `<llumi-copy-button>`.
93
+
94
+ ### CSS custom properties
95
+
96
+ Each token has a sensible `oklch` fallback.
97
+
98
+ | Token | Role | Fallback |
99
+ |-------|------|---------|
100
+ | `--llumi-color-success` | Border + icon colour in the downloaded state | `oklch(62.7% 0.194 149.214)` (green) |
101
+ | `--llumi-color-danger` | Border + icon colour in the error state | `oklch(57.7% 0.245 27.325)` (red) |
102
+ | `--llumi-color-surface` | Button background | `oklch(100% 0 0)` (white) |
103
+ | `--llumi-color-border` | Button border | `oklch(92% 0.004 286.32)` (light grey) |
104
+ | `--llumi-color-fg` | Icon colour (idle) | `oklch(21% 0.006 285.885)` (near-black) |
105
+ | `--llumi-color-ring` | Focus-visible outline | `oklch(55.8% 0.288 302.321)` (purple) |
106
+ | `--llumi-radius` | Button border-radius | `0.5rem` |
@@ -0,0 +1,177 @@
1
+ import { html as u } from "https://cdn.jsdelivr.net/npm/lit@3.3.3";
2
+ import { property as l, customElement as p } from "https://cdn.jsdelivr.net/npm/lit@3.3.3/decorators.js";
3
+ import { i as a } from "./icons-BaUbjt-v.js";
4
+ import { L as f } from "./llumi-element-BWRwgzW5.js";
5
+ import { defineMachine as h } 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 d = 1e3, O = h({
8
+ initialState: { name: "idle" },
9
+ states: {
10
+ idle: {
11
+ on: {
12
+ DOWNLOAD: {
13
+ to: "downloading",
14
+ data: ({ event: e }) => ({
15
+ text: e.text,
16
+ filename: e.filename,
17
+ mimeType: e.mimeType
18
+ })
19
+ }
20
+ }
21
+ },
22
+ downloading: {
23
+ onEnter: ({ state: e, send: t }) => {
24
+ try {
25
+ const i = URL.createObjectURL(
26
+ new Blob([e.text], { type: e.mimeType })
27
+ ), o = document.createElement("a");
28
+ o.href = i, o.download = e.filename, o.click(), URL.revokeObjectURL(i), queueMicrotask(
29
+ () => t({ type: "DOWNLOAD_SUCCESS", filename: e.filename })
30
+ );
31
+ } catch (i) {
32
+ queueMicrotask(() => t({ type: "DOWNLOAD_ERROR", error: i }));
33
+ }
34
+ },
35
+ on: {
36
+ DOWNLOAD_SUCCESS: { to: "downloaded" },
37
+ DOWNLOAD_ERROR: { to: "error" }
38
+ }
39
+ },
40
+ downloaded: {
41
+ onEnter: ({ send: e }) => {
42
+ const t = setTimeout(() => e({ type: "DONE" }), d);
43
+ return () => clearTimeout(t);
44
+ },
45
+ on: {
46
+ DONE: { to: "idle" },
47
+ DOWNLOAD: {
48
+ to: "downloading",
49
+ data: ({ event: e }) => ({
50
+ text: e.text,
51
+ filename: e.filename,
52
+ mimeType: e.mimeType
53
+ })
54
+ }
55
+ }
56
+ },
57
+ error: {
58
+ onEnter: ({ send: e }) => {
59
+ const t = setTimeout(() => e({ type: "DONE" }), d);
60
+ return () => clearTimeout(t);
61
+ },
62
+ on: {
63
+ DONE: { to: "idle" },
64
+ DOWNLOAD: {
65
+ to: "downloading",
66
+ data: ({ event: e }) => ({
67
+ text: e.text,
68
+ filename: e.filename,
69
+ mimeType: e.mimeType
70
+ })
71
+ }
72
+ }
73
+ }
74
+ }
75
+ });
76
+ var b = Object.defineProperty, w = Object.getOwnPropertyDescriptor, s = (e, t, i, o) => {
77
+ for (var n = o > 1 ? void 0 : o ? w(t, i) : t, c = e.length - 1, m; c >= 0; c--)
78
+ (m = e[c]) && (n = (o ? m(t, i, n) : m(n)) || n);
79
+ return o && n && b(t, i, n), n;
80
+ };
81
+ function y(e) {
82
+ throw new Error(`Unexpected state: ${JSON.stringify(e)}`);
83
+ }
84
+ let r = class extends f {
85
+ constructor() {
86
+ super(...arguments), this.filename = "", this.mimeType = "text/plain", this.title = "Download file";
87
+ }
88
+ /** Light DOM so the document-level base.css button style applies. */
89
+ createRenderRoot() {
90
+ return this;
91
+ }
92
+ connectedCallback() {
93
+ super.connectedCallback(), this.instance = O.newInstance().start(), this.unsubscribe = this.instance.subscribe(
94
+ ({ state: e, event: t }) => this.onTransition(e, t)
95
+ );
96
+ }
97
+ disconnectedCallback() {
98
+ var e, t;
99
+ super.disconnectedCallback(), (e = this.unsubscribe) == null || e.call(this), this.unsubscribe = void 0, (t = this.instance) == null || t.stop(), this.instance = void 0;
100
+ }
101
+ onTransition(e, t) {
102
+ (t == null ? void 0 : t.type) === "DOWNLOAD_SUCCESS" ? this.dispatchEvent(
103
+ new CustomEvent("llumi-download", {
104
+ detail: { filename: t.filename },
105
+ bubbles: !0,
106
+ composed: !0
107
+ })
108
+ ) : (t == null ? void 0 : t.type) === "DOWNLOAD_ERROR" && this.dispatchEvent(
109
+ new CustomEvent("llumi-download-error", {
110
+ detail: { error: t.error },
111
+ bubbles: !0,
112
+ composed: !0
113
+ })
114
+ ), this.requestUpdate();
115
+ }
116
+ onClick() {
117
+ var e, t;
118
+ if (!this.filename) {
119
+ console.warn(
120
+ '<llumi-download-button>: "filename" is required; ignoring click'
121
+ );
122
+ return;
123
+ }
124
+ (t = this.instance) == null || t.send({
125
+ type: "DOWNLOAD",
126
+ text: ((e = this.getValue) == null ? void 0 : e.call(this)) ?? "",
127
+ filename: this.filename,
128
+ mimeType: this.mimeType
129
+ });
130
+ }
131
+ viewFor(e) {
132
+ switch (e) {
133
+ case "idle":
134
+ return { icon: a.download, cls: "" };
135
+ case "downloading":
136
+ return { icon: a.spinner, cls: "is-working" };
137
+ case "downloaded":
138
+ return { icon: a.check, cls: "is-done" };
139
+ case "error":
140
+ return { icon: a.x, cls: "is-error" };
141
+ default:
142
+ return y(e);
143
+ }
144
+ }
145
+ render() {
146
+ var i;
147
+ const e = ((i = this.instance) == null ? void 0 : i.state.name) ?? "idle", t = this.viewFor(e);
148
+ return u`<button
149
+ type="button"
150
+ class=${t.cls}
151
+ title=${this.title}
152
+ aria-label=${this.title}
153
+ ?disabled=${e === "downloading"}
154
+ @click=${this.onClick}
155
+ >
156
+ <i>${t.icon}</i>
157
+ </button>`;
158
+ }
159
+ };
160
+ s([
161
+ l()
162
+ ], r.prototype, "filename", 2);
163
+ s([
164
+ l({ attribute: "mime-type" })
165
+ ], r.prototype, "mimeType", 2);
166
+ s([
167
+ l()
168
+ ], r.prototype, "title", 2);
169
+ s([
170
+ l({ attribute: !1 })
171
+ ], r.prototype, "getValue", 2);
172
+ r = s([
173
+ p("llumi-download-button")
174
+ ], r);
175
+ export {
176
+ r as LlumiDownloadButton
177
+ };
package/highlighter.md ADDED
@@ -0,0 +1,45 @@
1
+ # llumi-highlighter
2
+
3
+ Syntax-highlighted code block (Prism via `refractor`), with 4 themes, an optional
4
+ copy button, and line-range dimming. Renders in **shadow DOM** (theme/token CSS is
5
+ encapsulated).
6
+
7
+ ## Usage
8
+
9
+ Load the design-system base stylesheet once (for the document), then the component:
10
+
11
+ ```html
12
+ <link rel="stylesheet" href="@llumi/design-system/base.css" />
13
+ <script type="module" src="@llumi/design-system/highlighter"></script>
14
+
15
+ <!-- code via the `code` property (recommended) -->
16
+ <llumi-highlighter language="typescript"></llumi-highlighter>
17
+ <script>
18
+ document.querySelector("llumi-highlighter").code =
19
+ "const greet = (name) => console.log(name);";
20
+ </script>
21
+
22
+ <!-- or as text content -->
23
+ <llumi-highlighter language="rust">fn main() { println!("hi"); }</llumi-highlighter>
24
+ ```
25
+
26
+ ## Properties / attributes
27
+
28
+ | Name | Attr | Type | Default | Description |
29
+ |------|------|------|---------|-------------|
30
+ | `language` | `language` | `string` | `""` | Prism language id (e.g. `typescript`, `python`). Aliases: `ts`, `js`, `py`, `rs`, `sh`, `md`, `html`. Unsupported → plain text + a console warning. |
31
+ | `theme` | `theme` | `ghcolors \| oneLight \| oneDark \| dracula` | `ghcolors` | Color theme. |
32
+ | `code` | `code` | `string` | `""` | Code source; falls back to the element's text content. |
33
+ | `highlight` | — (property) | `[number, number][]` | — | 1-based line ranges. When set, line numbers show and other lines dim to 30% opacity. |
34
+ | `copyButton` | `copy-button` | `boolean` | `true` | Show the copy button. Disable with `copy-button="false"`. |
35
+
36
+ ## Events
37
+
38
+ The embedded copy button emits (bubbling, composed — they cross the shadow boundary):
39
+ `llumi-copy` `{ detail: { text } }` and `llumi-copy-error` `{ detail: { error } }`.
40
+
41
+ ## Supported languages
42
+
43
+ `markup`/`html`/`xml`, `css`, `javascript`/`js`, `jsx`, `typescript`/`ts`, `tsx`,
44
+ `json`, `bash`/`sh`/`shell`, `python`/`py`, `rust`/`rs`, `go`, `java`, `yaml`,
45
+ `markdown`/`md`, `sql`, `diff`. (Grammars load lazily on first use.)