@supersoniks/concorde 5.0.3 → 5.0.5

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 (151) hide show
  1. package/.agents/skills/concorde-component-docs/SKILL.md +194 -0
  2. package/.agents/skills/concorde-component-docs/template.md +45 -0
  3. package/ai/cursor/rules/concorde-theme.mdc +1 -1
  4. package/ai/cursor/rules/concorde.mdc +1 -1
  5. package/ai/skills/concorde/SKILL.md +1 -1
  6. package/ai/skills/concorde-theme/SKILL.md +21 -10
  7. package/build-infos.json +1 -1
  8. package/concorde-core.bundle.js +515 -521
  9. package/concorde-core.es.js +5151 -5056
  10. package/dist/concorde-core.bundle.js +515 -521
  11. package/dist/concorde-core.es.js +5151 -5056
  12. package/dist/docs-mock-api-sw.js +2 -0
  13. package/dist/docs-mock-api-sw.js.map +2 -2
  14. package/docs/assets/index-CD4WyL6o.css +1 -0
  15. package/docs/assets/{index-BnK6OS7w.js → index-wVZpLVYW.js} +815 -808
  16. package/docs/crawl/core/components/ui/alert/alert.html +76 -5
  17. package/docs/crawl/core/components/ui/alert-messages/alert-messages.html +113 -5
  18. package/docs/crawl/core/components/ui/badge/badge.html +57 -8
  19. package/docs/crawl/core/components/ui/captcha/captcha.html +90 -8
  20. package/docs/crawl/core/components/ui/card/card.html +122 -12
  21. package/docs/crawl/core/components/ui/divider/divider.html +117 -31
  22. package/docs/crawl/core/components/ui/form/fieldset/fieldset.html +232 -101
  23. package/docs/crawl/core/components/ui/form/form-actions/form-actions.html +95 -52
  24. package/docs/crawl/core/components/ui/form/form-layout/form-layout.html +97 -38
  25. package/docs/crawl/core/components/ui/group/group.html +60 -38
  26. package/docs/crawl/core/components/ui/icon/icon.html +136 -47
  27. package/docs/crawl/core/components/ui/image/image.html +118 -6
  28. package/docs/crawl/core/components/ui/link/link.html +65 -7
  29. package/docs/crawl/core/components/ui/loader/loader.html +97 -23
  30. package/docs/crawl/core/components/ui/menu/menu.html +162 -90
  31. package/docs/crawl/core/components/ui/modal/modal.html +275 -50
  32. package/docs/crawl/core/components/ui/pop/pop.html +242 -124
  33. package/docs/crawl/core/components/ui/progress/progress.html +103 -30
  34. package/docs/crawl/core/components/ui/table/table.html +303 -171
  35. package/docs/crawl/core/components/ui/theme/theme.html +131 -0
  36. package/docs/crawl/core/components/ui/toast/toast.html +170 -59
  37. package/docs/crawl/core/components/ui/tooltip/tooltip.html +90 -29
  38. package/docs/crawl/docs/_decorators/ancestor-attribute.html +3 -2
  39. package/docs/crawl/docs/_getting-started/start.html +1 -1
  40. package/docs/crawl/docs/_getting-started/theming.html +311 -63
  41. package/docs/crawl/hubs/form-components.html +71 -49
  42. package/docs/crawl/index.html +7 -6
  43. package/docs/docs-mock-api-sw.js +2 -0
  44. package/docs/docs-mock-api-sw.js.map +2 -2
  45. package/docs/index.html +6 -4
  46. package/docs/llms-full.txt +1468 -405
  47. package/docs/llms.txt +23 -30
  48. package/docs/sitemap.xml +3 -0
  49. package/docs/src/core/components/ui/alert/alert.md +21 -2
  50. package/docs/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  51. package/docs/src/core/components/ui/badge/badge.md +19 -6
  52. package/docs/src/core/components/ui/captcha/captcha.md +65 -6
  53. package/docs/src/core/components/ui/card/card.md +73 -10
  54. package/docs/src/core/components/ui/divider/divider.md +107 -13
  55. package/docs/src/core/components/ui/form/fieldset/fieldset.md +175 -99
  56. package/docs/src/core/components/ui/form/form-actions/form-actions.md +75 -52
  57. package/docs/src/core/components/ui/form/form-layout/form-layout.md +109 -34
  58. package/docs/src/core/components/ui/group/group.md +36 -36
  59. package/docs/src/core/components/ui/icon/icon.md +132 -43
  60. package/docs/src/core/components/ui/image/image.md +35 -3
  61. package/docs/src/core/components/ui/link/link.md +43 -5
  62. package/docs/src/core/components/ui/loader/loader.md +79 -22
  63. package/docs/src/core/components/ui/menu/menu.md +133 -92
  64. package/docs/src/core/components/ui/modal/modal.md +163 -47
  65. package/docs/src/core/components/ui/pop/pop.md +217 -123
  66. package/docs/src/core/components/ui/progress/progress.md +76 -30
  67. package/docs/src/core/components/ui/table/table.md +147 -171
  68. package/docs/src/core/components/ui/theme/theme.md +122 -0
  69. package/docs/src/core/components/ui/toast/toast.md +108 -58
  70. package/docs/src/core/components/ui/tooltip/tooltip.md +68 -26
  71. package/docs/src/docs/_decorators/ancestor-attribute.md +3 -2
  72. package/docs/src/docs/_getting-started/start.md +1 -1
  73. package/docs/src/docs/_getting-started/theming.md +223 -61
  74. package/docs/src/docs/search/docs-search.json +2504 -399
  75. package/docs/src/tsconfig.json +18 -0
  76. package/index.html +4 -2
  77. package/package.json +7 -1
  78. package/public/docs-mock-api-sw.js +2 -0
  79. package/public/docs-mock-api-sw.js.map +2 -2
  80. package/src/core/components/ui/_css/align.ts +1 -0
  81. package/src/core/components/ui/_css/type.ts +86 -8
  82. package/src/core/components/ui/_i18n/ui-aria-labels.ts +8 -0
  83. package/src/core/components/ui/alert/alert.md +21 -2
  84. package/src/core/components/ui/alert-messages/alert-messages.md +85 -0
  85. package/src/core/components/ui/badge/badge.md +19 -6
  86. package/src/core/components/ui/badge/badge.ts +8 -9
  87. package/src/core/components/ui/button/button.ts +5 -15
  88. package/src/core/components/ui/captcha/captcha.md +65 -6
  89. package/src/core/components/ui/card/card.md +73 -10
  90. package/src/core/components/ui/card/card.ts +24 -22
  91. package/src/core/components/ui/divider/divider.md +107 -13
  92. package/src/core/components/ui/divider/divider.ts +40 -33
  93. package/src/core/components/ui/form/fieldset/fieldset.md +175 -99
  94. package/src/core/components/ui/form/fieldset/fieldset.ts +15 -28
  95. package/src/core/components/ui/form/fieldset/legend.ts +13 -13
  96. package/src/core/components/ui/form/form-actions/form-actions.md +75 -52
  97. package/src/core/components/ui/form/form-actions/form-actions.ts +7 -5
  98. package/src/core/components/ui/form/form-layout/form-layout.md +109 -34
  99. package/src/core/components/ui/form/form-layout/form-layout.ts +27 -24
  100. package/src/core/components/ui/form/textarea/textarea.ts +4 -3
  101. package/src/core/components/ui/group/group.md +36 -36
  102. package/src/core/components/ui/group/group.ts +5 -10
  103. package/src/core/components/ui/icon/icon.md +132 -43
  104. package/src/core/components/ui/image/image.md +35 -3
  105. package/src/core/components/ui/link/link.md +43 -5
  106. package/src/core/components/ui/loader/loader.md +79 -22
  107. package/src/core/components/ui/loader/loader.ts +67 -27
  108. package/src/core/components/ui/loader/styles/fixed.ts +6 -11
  109. package/src/core/components/ui/menu/menu.md +133 -92
  110. package/src/core/components/ui/menu/menu.ts +53 -58
  111. package/src/core/components/ui/modal/modal.md +163 -47
  112. package/src/core/components/ui/modal/modal.ts +2 -4
  113. package/src/core/components/ui/pop/pop.md +217 -123
  114. package/src/core/components/ui/pop/pop.ts +0 -1
  115. package/src/core/components/ui/progress/progress.md +76 -30
  116. package/src/core/components/ui/progress/progress.ts +25 -56
  117. package/src/core/components/ui/table/table-caption.ts +2 -2
  118. package/src/core/components/ui/table/table-tbody.ts +3 -3
  119. package/src/core/components/ui/table/table-td.ts +23 -18
  120. package/src/core/components/ui/table/table-th.ts +8 -8
  121. package/src/core/components/ui/table/table-tr.ts +4 -4
  122. package/src/core/components/ui/table/table.md +147 -171
  123. package/src/core/components/ui/table/table.ts +20 -19
  124. package/src/core/components/ui/theme/theme-collection/auto.ts +15 -0
  125. package/src/core/components/ui/theme/theme-collection/core-variables.ts +8 -31
  126. package/src/core/components/ui/theme/theme-collection/dark.ts +1 -7
  127. package/src/core/components/ui/theme/theme-collection/light.ts +30 -26
  128. package/src/core/components/ui/theme/theme.md +122 -0
  129. package/src/core/components/ui/theme/theme.ts +30 -7
  130. package/src/core/components/ui/toast/toast-item.ts +6 -9
  131. package/src/core/components/ui/toast/toast.md +108 -58
  132. package/src/core/components/ui/toast/types.ts +1 -1
  133. package/src/core/components/ui/tooltip/tooltip.md +68 -26
  134. package/src/core/decorators/subscriber/ancestorAttribute.spec.ts +26 -0
  135. package/src/core/decorators/subscriber/ancestorAttribute.ts +3 -4
  136. package/src/core/utils/AncestorAttributeObserver.ts +183 -70
  137. package/src/docs/_decorators/ancestor-attribute.md +3 -2
  138. package/src/docs/_getting-started/start.md +1 -1
  139. package/src/docs/_getting-started/theming.md +223 -61
  140. package/src/docs/code.ts +125 -58
  141. package/src/docs/header/header.ts +62 -54
  142. package/src/docs/mock-api/router.ts +2 -0
  143. package/src/docs/navigation/navigation.ts +6 -3
  144. package/src/docs/search/docs-search.json +2504 -399
  145. package/src/docs/search/markdown-renderer.ts +6 -6
  146. package/src/docs/search/search.ts +4 -4
  147. package/src/docs/tailwind/css/tailwind.css +6 -5
  148. package/src/tsconfig.json +18 -0
  149. package/src/tsconfig.tsbuildinfo +1 -1
  150. package/tailwind.config.js +19 -0
  151. package/docs/assets/index--GpD7R7a.css +0 -1
@@ -1,12 +1,27 @@
1
- import { html, LitElement, css } from "lit";
1
+ import { html, LitElement, css, PropertyValues } from "lit";
2
2
  import { customElement, property } from "lit/decorators.js";
3
+ import { classMap } from "lit/directives/class-map.js";
3
4
 
4
5
  import { inline } from "@supersoniks/concorde/core/components/ui/loader/styles/inline";
5
6
  import { fixed } from "@supersoniks/concorde/core/components/ui/loader/styles/fixed";
6
7
  import { Theme } from "@supersoniks/concorde/core/components/ui/theme/theme";
7
- export type LoaderMode = "inline" | "fixed" | "noDelay";
8
- type LoaderConf = { mode?: string; container?: HTMLElement; noDelay?: boolean };
8
+ import {
9
+ resolveUiLabel,
10
+ uiAriaLabels,
11
+ } from "@supersoniks/concorde/core/components/ui/_i18n/ui-aria-labels";
12
+
13
+ export type LoaderMode = "inline" | "fixed";
14
+
15
+ export type LoaderConf = {
16
+ mode?: LoaderMode;
17
+ container?: HTMLElement;
18
+ noDelay?: boolean;
19
+ /** Screen reader announcement when the loader is injected (e.g. global overlay). */
20
+ announce?: boolean;
21
+ };
22
+
9
23
  const tagName = "sonic-loader";
24
+
10
25
  @customElement(tagName)
11
26
  export class Loader extends LitElement {
12
27
  static styles = [
@@ -42,45 +57,70 @@ export class Loader extends LitElement {
42
57
  }
43
58
  `,
44
59
  ];
45
- static loader: Loader;
60
+
61
+ static loader: Loader | null = null;
46
62
  static callCounter = 0;
47
- static show(conf?: LoaderConf) {
48
- if (!Loader.loader)
49
- Loader.loader = document.createElement("sonic-loader") as Loader;
50
- const loader: Loader = Loader.loader;
51
- if (!conf) conf = {};
52
- if (conf.mode) loader.setAttribute("mode", conf.mode);
53
- if (conf.noDelay) loader.setAttribute("noDelay", "");
54
-
55
- if (!conf.container) {
56
- conf.container = Theme.getPopContainer();
57
- conf.mode = "fixed";
63
+
64
+ static show(conf: LoaderConf = {}) {
65
+ if (!Loader.loader) {
66
+ Loader.loader = document.createElement(tagName) as Loader;
58
67
  }
68
+ const loader = Loader.loader;
59
69
 
60
- conf.container.appendChild(loader);
70
+ const container = conf.container ?? Theme.getPopContainer();
71
+ const mode: LoaderMode = conf.container ? (conf.mode ?? "fixed") : "fixed";
72
+ const noDelay = conf.noDelay ?? false;
73
+
74
+ loader.mode = mode;
75
+ loader.noDelay = noDelay;
76
+ loader.announce = conf.announce ?? false;
77
+ container.appendChild(loader);
61
78
  Loader.callCounter++;
62
79
  }
63
80
 
64
81
  static hide() {
82
+ if (Loader.callCounter <= 0) return;
65
83
  Loader.callCounter--;
66
84
  if (Loader.callCounter > 0) return;
67
- if (Loader.loader) Loader.loader.remove();
85
+ Loader.loader?.remove();
68
86
  }
69
87
 
88
+ /** Display mode: inline (in content) or fixed (viewport overlay). */
89
+ @property({ type: String }) mode: LoaderMode = "fixed";
90
+ /** Skip the initial fade-in delay before the loader appears. */
91
+ @property({ type: Boolean }) noDelay = false;
70
92
  /**
71
- * Mode d'affichage du loader
72
- * * inline : Loader dans le contenu
73
- * * fixed : Loader global par dessus la page
93
+ * When true, exposes `role="status"` and `aria-live="polite"` on the host (like `sonic-alert`).
94
+ * Use when the loader appears after user action; default inline loaders stay decorative.
74
95
  */
75
- @property({ type: String }) mode: LoaderMode = "fixed";
76
- @property({ type: Boolean }) noDelay: boolean = false;
96
+ @property({ type: Boolean, reflect: true }) announce = false;
97
+
98
+ willUpdate(changed: PropertyValues<this>) {
99
+ if (changed.has("announce")) {
100
+ this._syncAnnounceA11y();
101
+ }
102
+ }
103
+
104
+ private _syncAnnounceA11y() {
105
+ if (!this.announce) {
106
+ this.removeAttribute("role");
107
+ this.removeAttribute("aria-live");
108
+ this.removeAttribute("aria-label");
109
+ return;
110
+ }
111
+ this.setAttribute("role", "status");
112
+ this.setAttribute("aria-live", "polite");
113
+ this.setAttribute("aria-label", resolveUiLabel(uiAriaLabels.loading));
114
+ }
77
115
 
78
116
  render() {
79
- return html`<div
80
- class="sonic-loader sonic-loader--${this.mode} ${this.noDelay
81
- ? "sonic-loader--nodelay"
82
- : ""} "
83
- >
117
+ const classes = {
118
+ "sonic-loader": true,
119
+ [`sonic-loader--${this.mode}`]: true,
120
+ "sonic-loader--nodelay": this.noDelay,
121
+ };
122
+
123
+ return html`<div aria-hidden="true" class=${classMap(classes)}>
84
124
  <div></div>
85
125
  <div></div>
86
126
  <div></div>
@@ -22,7 +22,7 @@ export const fixed = css`
22
22
  position: fixed;
23
23
  top: 50%;
24
24
  left: 50%;
25
- transform: transateY(-50%) translateX(-50%);
25
+ transform: translate(-50%, -50%);
26
26
  z-index: 999;
27
27
  }
28
28
 
@@ -37,20 +37,15 @@ export const fixed = css`
37
37
  display: none !important;
38
38
  }
39
39
  .sonic-loader--fixed > div {
40
- background-color: var(--sc-_loader-bg);
41
- width: 5rem;
42
- height: 5rem;
43
- border-radius: 100%;
44
- margin: 2px;
45
- animation-fill-mode: both;
46
40
  position: absolute;
47
- top: 0px;
48
- opacity: 0;
49
- margin: 0;
50
41
  top: -2.5rem;
51
42
  left: -2.5rem;
52
43
  width: 5rem;
53
44
  height: 5rem;
54
- animation: sonic-loader--fixed 1s 0s linear infinite;
45
+ border-radius: 100%;
46
+ background-color: var(--sc-_loader-bg);
47
+ opacity: 0;
48
+ animation: sonic-loader--fixed 1s linear infinite;
49
+ animation-fill-mode: both;
55
50
  }
56
51
  `;
@@ -1,9 +1,35 @@
1
1
  # Menu
2
2
 
3
+ **`sonic-menu`** lays out navigation or actions as a **`direction`** row or column of **`sonic-menu-item`** entries (ghost **`variant`** and block **`shape`** by default), optional **`sonic-divider`** separators, and overflow content in the **`more`** slot (popover “…” trigger). Set **`href`** / **`pushstate`** / **`autoActive`** on each **`sonic-menu-item`**—same API as **`sonic-button`**—not on the menu host.
4
+
5
+ ## Basic example
6
+
7
+ <sonic-code>
8
+ <template>
9
+ <sonic-menu direction="row">
10
+ <sonic-menu-item variant="ghost">
11
+ <sonic-icon library="iconoir" name="home" slot="prefix"></sonic-icon>
12
+ Home
13
+ </sonic-menu-item>
14
+ <sonic-menu-item>
15
+ <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
16
+ Profile
17
+ </sonic-menu-item>
18
+ <sonic-menu-item type="danger">
19
+ <sonic-icon library="iconoir" name="log-out" slot="prefix"></sonic-icon>
20
+ Log out
21
+ </sonic-menu-item>
22
+ </sonic-menu>
23
+ </template>
24
+ </sonic-code>
25
+
3
26
  ## Direction
27
+
28
+ Default **`direction`** is **`column`**. Use **`row`** for horizontal toolbars or tabs.
29
+
4
30
  <sonic-code>
5
31
  <template>
6
- <sonic-menu direction="row" >
32
+ <sonic-menu direction="row">
7
33
  <sonic-menu-item variant="ghost">
8
34
  <sonic-icon library="iconoir" name="arrow-right" slot="prefix"></sonic-icon>
9
35
  Row
@@ -12,11 +38,11 @@
12
38
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
13
39
  Profile
14
40
  </sonic-menu-item>
15
- <sonic-menu-item >
41
+ <sonic-menu-item>
16
42
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
17
43
  History
18
44
  </sonic-menu-item>
19
- <sonic-menu-item >
45
+ <sonic-menu-item>
20
46
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
21
47
  Orders
22
48
  </sonic-menu-item>
@@ -25,7 +51,7 @@
25
51
  Log out
26
52
  </sonic-menu-item>
27
53
  </sonic-menu>
28
- <sonic-menu direction ="column" >
54
+ <sonic-menu direction="column">
29
55
  <sonic-menu-item variant="ghost">
30
56
  <sonic-icon library="iconoir" name="arrow-down" slot="prefix"></sonic-icon>
31
57
  Column
@@ -34,11 +60,11 @@
34
60
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
35
61
  Profile
36
62
  </sonic-menu-item>
37
- <sonic-menu-item >
63
+ <sonic-menu-item>
38
64
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
39
65
  History
40
66
  </sonic-menu-item>
41
- <sonic-menu-item >
67
+ <sonic-menu-item>
42
68
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
43
69
  Orders
44
70
  </sonic-menu-item>
@@ -51,90 +77,83 @@
51
77
  </sonic-code>
52
78
 
53
79
  ## Size
80
+
81
+ **`size`** on the menu propagates to items and the **`more`** trigger when they omit their own **`size`**.
82
+
54
83
  <sonic-code>
55
84
  <template>
56
85
  <div class="grid gap-3">
57
86
  <sonic-menu size="xs" direction="row">
58
- <sonic-menu-item>
59
- XS
60
- </sonic-menu-item>
87
+ <sonic-menu-item>XS</sonic-menu-item>
61
88
  <sonic-menu-item>
62
89
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
63
90
  Profile
64
91
  </sonic-menu-item>
65
- <sonic-menu-item >
92
+ <sonic-menu-item>
66
93
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
67
94
  History
68
95
  </sonic-menu-item>
69
- <sonic-menu-item >
96
+ <sonic-menu-item>
70
97
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
71
98
  Orders
72
99
  </sonic-menu-item>
73
100
  </sonic-menu>
74
101
  <sonic-menu size="sm" direction="row">
75
- <sonic-menu-item>
76
- Small
77
- </sonic-menu-item>
102
+ <sonic-menu-item>Small</sonic-menu-item>
78
103
  <sonic-menu-item>
79
104
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
80
105
  Profile
81
106
  </sonic-menu-item>
82
- <sonic-menu-item >
107
+ <sonic-menu-item>
83
108
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
84
109
  History
85
110
  </sonic-menu-item>
86
- <sonic-menu-item >
111
+ <sonic-menu-item>
87
112
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
88
113
  Orders
89
114
  </sonic-menu-item>
90
115
  </sonic-menu>
91
116
  <sonic-menu direction="row">
92
- <sonic-menu-item>
93
- Medium
94
- </sonic-menu-item>
117
+ <sonic-menu-item>Medium</sonic-menu-item>
95
118
  <sonic-menu-item>
96
119
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
97
120
  Profile
98
121
  </sonic-menu-item>
99
- <sonic-menu-item >
122
+ <sonic-menu-item>
100
123
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
101
124
  History
102
125
  </sonic-menu-item>
103
- <sonic-menu-item >
126
+ <sonic-menu-item>
104
127
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
105
128
  Orders
106
129
  </sonic-menu-item>
107
130
  </sonic-menu>
108
131
  <sonic-menu size="lg" direction="row">
109
- <sonic-menu-item>
110
- Large
111
- </sonic-menu-item>
132
+ <sonic-menu-item>Large</sonic-menu-item>
112
133
  <sonic-menu-item>
113
134
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
114
135
  Profile
115
136
  </sonic-menu-item>
116
- <sonic-menu-item >
137
+ <sonic-menu-item>
117
138
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
118
139
  History
119
140
  </sonic-menu-item>
120
- <sonic-menu-item >
141
+ <sonic-menu-item>
121
142
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
122
143
  Orders
123
144
  </sonic-menu-item>
124
145
  </sonic-menu>
125
146
  <sonic-menu size="xl" direction="row">
126
- <sonic-menu-item>
127
- XL
128
- </sonic-menu-item>
147
+ <sonic-menu-item>XL</sonic-menu-item>
129
148
  <sonic-menu-item>
130
149
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
131
150
  Profile
132
151
  </sonic-menu-item>
133
- <sonic-menu-item >
152
+ <sonic-menu-item>
134
153
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
135
154
  History
136
155
  </sonic-menu-item>
137
- <sonic-menu-item >
156
+ <sonic-menu-item>
138
157
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
139
158
  Orders
140
159
  </sonic-menu-item>
@@ -144,72 +163,73 @@
144
163
  </sonic-code>
145
164
 
146
165
  ## Shadow
166
+
167
+ Optional **`shadow`** wraps the menu surface (no shadow when omitted).
168
+
147
169
  <sonic-code>
148
170
  <template>
149
171
  <div class="grid gap-3">
150
172
  <sonic-menu direction="row">
151
- <sonic-menu-item>
152
- None
153
- </sonic-menu-item>
173
+ <sonic-menu-item>None</sonic-menu-item>
154
174
  </sonic-menu>
155
175
  <sonic-menu shadow="sm" direction="row">
156
- <sonic-menu-item>
157
- Small
158
- </sonic-menu-item>
176
+ <sonic-menu-item>Small</sonic-menu-item>
159
177
  </sonic-menu>
160
178
  <sonic-menu shadow="md" direction="row">
161
- <sonic-menu-item>
162
- Medium
163
- </sonic-menu-item>
179
+ <sonic-menu-item>Medium</sonic-menu-item>
164
180
  </sonic-menu>
165
181
  <sonic-menu shadow="lg" direction="row">
166
- <sonic-menu-item>
167
- Large
168
- </sonic-menu-item>
182
+ <sonic-menu-item>Large</sonic-menu-item>
169
183
  </sonic-menu>
170
184
  </div>
171
185
  </template>
172
186
  </sonic-code>
173
187
 
174
188
  ## Align
189
+
190
+ **`align`** propagates to items except square / circle **`shape`**.
191
+
175
192
  <sonic-code>
176
193
  <template>
177
- <sonic-menu align="center">
178
- <sonic-menu-item variant="ghost">
179
- <sonic-icon library="iconoir" name="home"></sonic-icon>
180
- Home
181
- </sonic-menu-item>
182
- <sonic-menu-item>
183
- <sonic-icon library="iconoir" name="user"></sonic-icon>
184
- Profile
185
- </sonic-menu-item>
186
- </sonic-menu>
187
- <sonic-menu align="left">
188
- <sonic-menu-item variant="ghost">
189
- <sonic-icon library="iconoir" name="home"></sonic-icon>
190
- Home
191
- </sonic-menu-item>
192
- <sonic-menu-item>
193
- <sonic-icon library="iconoir" name="user"></sonic-icon>
194
- Profile
195
- </sonic-menu-item>
196
- </sonic-menu>
197
- <sonic-menu align="right">
198
- <sonic-menu-item variant="ghost">
199
- <sonic-icon library="iconoir" name="home"></sonic-icon>
200
- Home
201
- </sonic-menu-item>
202
- <sonic-menu-item>
203
- <sonic-icon library="iconoir" name="user"></sonic-icon>
204
- Profile
205
- </sonic-menu-item>
206
- </sonic-menu>
194
+ <div class="grid gap-3">
195
+ <sonic-menu align="center">
196
+ <sonic-menu-item variant="ghost">
197
+ <sonic-icon library="iconoir" name="home"></sonic-icon>
198
+ Home
199
+ </sonic-menu-item>
200
+ <sonic-menu-item>
201
+ <sonic-icon library="iconoir" name="user"></sonic-icon>
202
+ Profile
203
+ </sonic-menu-item>
204
+ </sonic-menu>
205
+ <sonic-menu align="left">
206
+ <sonic-menu-item variant="ghost">
207
+ <sonic-icon library="iconoir" name="home"></sonic-icon>
208
+ Home
209
+ </sonic-menu-item>
210
+ <sonic-menu-item>
211
+ <sonic-icon library="iconoir" name="user"></sonic-icon>
212
+ Profile
213
+ </sonic-menu-item>
214
+ </sonic-menu>
215
+ <sonic-menu align="right">
216
+ <sonic-menu-item variant="ghost">
217
+ <sonic-icon library="iconoir" name="home"></sonic-icon>
218
+ Home
219
+ </sonic-menu-item>
220
+ <sonic-menu-item>
221
+ <sonic-icon library="iconoir" name="user"></sonic-icon>
222
+ Profile
223
+ </sonic-menu-item>
224
+ </sonic-menu>
225
+ </div>
207
226
  </template>
208
227
  </sonic-code>
209
228
 
229
+ ## More
210
230
 
231
+ Assign nodes to **`slot="more"`** to show the overflow popover. The trigger appears only when the slot has content. Icon orientation follows **`direction`** (vertical ellipsis in a row menu).
211
232
 
212
- ## More
213
233
  <sonic-code>
214
234
  <template>
215
235
  <sonic-menu direction="row">
@@ -221,20 +241,20 @@
221
241
  <sonic-icon library="iconoir" name="user"></sonic-icon>
222
242
  Profile
223
243
  </sonic-menu-item>
224
- <sonic-menu-item >
244
+ <sonic-menu-item>
225
245
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
226
246
  History
227
247
  </sonic-menu-item>
228
- <sonic-menu-item >
248
+ <sonic-menu-item>
229
249
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
230
250
  Orders
231
251
  </sonic-menu-item>
232
252
  <sonic-menu slot="more">
233
- <sonic-menu-item >
253
+ <sonic-menu-item>
234
254
  <sonic-icon library="iconoir" name="settings" slot="prefix"></sonic-icon>
235
255
  Settings
236
256
  </sonic-menu-item>
237
- <sonic-menu-item >
257
+ <sonic-menu-item>
238
258
  <sonic-icon library="iconoir" name="chat-bubble" slot="prefix"></sonic-icon>
239
259
  Messages
240
260
  </sonic-menu-item>
@@ -249,6 +269,9 @@
249
269
  </sonic-code>
250
270
 
251
271
  ## Scrollable
272
+
273
+ With **`scrollable`**, the main slot scrolls with edge fade masks; drag-to-scroll works on pointer devices. When exactly one item is **`active`**, the menu scrolls it into view.
274
+
252
275
  <sonic-code>
253
276
  <template>
254
277
  <sonic-menu direction="row" scrollable>
@@ -260,14 +283,15 @@
260
283
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
261
284
  Profile
262
285
  </sonic-menu-item>
263
- <sonic-menu-item >
286
+ <sonic-menu-item>
264
287
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
265
288
  History
266
289
  </sonic-menu-item>
267
- <sonic-menu-item >
290
+ <sonic-menu-item>
268
291
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
269
292
  Orders
270
- </sonic-menu-item> <sonic-menu-item variant="ghost">
293
+ </sonic-menu-item>
294
+ <sonic-menu-item variant="ghost">
271
295
  <sonic-icon library="iconoir" name="home" slot="prefix"></sonic-icon>
272
296
  Home
273
297
  </sonic-menu-item>
@@ -275,14 +299,15 @@
275
299
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
276
300
  Profile
277
301
  </sonic-menu-item>
278
- <sonic-menu-item >
302
+ <sonic-menu-item>
279
303
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
280
304
  History
281
305
  </sonic-menu-item>
282
- <sonic-menu-item >
306
+ <sonic-menu-item>
283
307
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
284
308
  Orders
285
- </sonic-menu-item> <sonic-menu-item variant="ghost">
309
+ </sonic-menu-item>
310
+ <sonic-menu-item variant="ghost">
286
311
  <sonic-icon library="iconoir" name="home" slot="prefix"></sonic-icon>
287
312
  Home
288
313
  </sonic-menu-item>
@@ -290,28 +315,28 @@
290
315
  <sonic-icon library="iconoir" name="user" slot="prefix"></sonic-icon>
291
316
  Profile
292
317
  </sonic-menu-item>
293
- <sonic-menu-item >
318
+ <sonic-menu-item>
294
319
  <sonic-icon library="iconoir" name="clock-outline" slot="prefix"></sonic-icon>
295
320
  History
296
321
  </sonic-menu-item>
297
- <sonic-menu-item >
322
+ <sonic-menu-item>
298
323
  <sonic-icon library="iconoir" name="bag" slot="prefix"></sonic-icon>
299
324
  Orders
300
325
  </sonic-menu-item>
301
- <sonic-menu-item >
326
+ <sonic-menu-item>
302
327
  <sonic-icon library="iconoir" name="settings" slot="prefix"></sonic-icon>
303
328
  Settings
304
329
  </sonic-menu-item>
305
- <sonic-menu-item >
330
+ <sonic-menu-item>
306
331
  <sonic-icon library="iconoir" name="chat-bubble" slot="prefix"></sonic-icon>
307
332
  Messages
308
333
  </sonic-menu-item>
309
334
  <sonic-menu slot="more">
310
- <sonic-menu-item >
335
+ <sonic-menu-item>
311
336
  <sonic-icon library="iconoir" name="settings" slot="prefix"></sonic-icon>
312
337
  Settings
313
338
  </sonic-menu-item>
314
- <sonic-menu-item >
339
+ <sonic-menu-item>
315
340
  <sonic-icon library="iconoir" name="chat-bubble" slot="prefix"></sonic-icon>
316
341
  Messages
317
342
  </sonic-menu-item>
@@ -321,9 +346,25 @@
321
346
  Log out
322
347
  </sonic-menu-item>
323
348
  </sonic-menu>
324
-
349
+ </sonic-menu>
325
350
  </template>
326
351
  </sonic-code>
327
352
 
353
+ ## API reference
354
+
355
+ | Attribute | Values | Description |
356
+ |----------|---------|-------------|
357
+ | `direction` | `column` (default) · `row` | Vertical list or horizontal bar |
358
+ | `align` | `left` (default) · `center` · `right` | Alignment propagated to items (except square / circle **`shape`**) |
359
+ | `size` | `xs` · `sm` · `md` · `lg` · `xl` | Propagated to items and the **`more`** trigger when unset on the item |
360
+ | `shadow` | `sm` · `md` · `lg` | Shadow around the menu; omitted for none |
361
+ | `minWidth` | CSS length | Minimum width of the container (default `0`) |
362
+ | `scrollable` | boolean | Scroll with edge fade; auto-scroll when a single item is **`active`** |
363
+ | `moreShape` | `circle` (default) · `square` | Shape of the **`more`** slot trigger button |
364
+
365
+ | Slot | Description |
366
+ |------|-------------|
367
+ | *(default)* | Visible items: **`sonic-menu-item`**, **`sonic-divider`**, nested **`sonic-menu`** |
368
+ | `more` | Popover content for the “…” control; shown only when the slot has assigned nodes |
328
369
 
329
-
370
+ **`sonic-menu-item`** extends **`sonic-button`** (defaults: **`variant="ghost"`**, **`shape="block"`**). Use the button docs for **`type`**, **`variant`**, **`href`**, **`pushstate`**, **`autoActive`**, and item slots.