@intechstudio/grid-uikit 1.20260626.1315 → 1.20260713.1934

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.
@@ -65,7 +65,8 @@
65
65
  <span>&#9660;</span>
66
66
  </button>
67
67
  {#if $open}
68
- <div {...$menu} use:menu class="menu">
68
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
69
+ <div {...$menu} use:menu on:mousedown|preventDefault class="menu">
69
70
  {#each options as item}
70
71
  <div
71
72
  {...$option({ value: item.value, label: item.title })}
@@ -23,6 +23,8 @@ declare const MeltSelect: $$__sveltets_2_IsomorphicComponent<{
23
23
  title?: string;
24
24
  valueInfoEnabled?: boolean;
25
25
  }, {
26
+ mousedown: MouseEvent;
27
+ } & {
26
28
  [evt: string]: CustomEvent<any>;
27
29
  }, {}, {}, string>;
28
30
  type MeltSelect = InstanceType<typeof MeltSelect>;
@@ -150,6 +150,10 @@
150
150
  button.grouped {
151
151
  border-top-right-radius: 0;
152
152
  border-bottom-right-radius: 0;
153
+ /* Cap the label width so a long selected label truncates (…) instead
154
+ of stretching the split button. The button already has
155
+ overflow/ellipsis/nowrap; it just needs a width bound to act on. */
156
+ max-width: 16em;
153
157
  }
154
158
 
155
159
  button.style-normal {
@@ -1,11 +1,234 @@
1
- <div class="button-group">
2
- <slot />
1
+ <script lang="ts">
2
+ import { createSelect, melt } from "@melt-ui/svelte";
3
+
4
+ export let options: {
5
+ title: string;
6
+ value: any;
7
+ onclick?: (value: any) => void;
8
+ }[] = [];
9
+ export let style: "normal" | "outlined" | "accept" = "normal";
10
+ export let disabled: boolean = false;
11
+ export let target: any = undefined;
12
+
13
+ function getDefaultSelected() {
14
+ if (!options?.length) return undefined;
15
+ const obj = options.find((e) => e.value === target);
16
+ return obj ? { label: obj.title, value: obj.value } : undefined;
17
+ }
18
+
19
+ const {
20
+ elements: { menu, option, trigger },
21
+ states: { selected, selectedLabel, open },
22
+ helpers: { isSelected },
23
+ } = createSelect({
24
+ disabled: disabled,
25
+ forceVisible: true,
26
+ positioning: {
27
+ placement: "bottom-start",
28
+ fitViewport: true,
29
+ },
30
+ defaultSelected: getDefaultSelected(),
31
+ });
32
+
33
+ $: if ($selected) {
34
+ handleSelectionChange();
35
+ }
36
+
37
+ $: if (target != null) {
38
+ handleTargetChange();
39
+ }
40
+
41
+ function handleTargetChange() {
42
+ if ($selected?.value === target) return;
43
+ const obj = options.find((e) => e.value === target);
44
+ selected.set({ label: obj?.title ?? "", value: obj?.value });
45
+ }
46
+
47
+ function handleSelectionChange() {
48
+ if (!$selected || $selected.value === target) return;
49
+ target = $selected.value;
50
+ }
51
+
52
+ function closeDropdown() {
53
+ open.set(false);
54
+ }
55
+
56
+ function handleAction() {
57
+ if (!options || !$selected) return;
58
+ const item = options.find((e) => e.value === $selected.value);
59
+ if (item?.onclick) {
60
+ item.onclick($selected.value);
61
+ }
62
+ }
63
+ </script>
64
+
65
+ <div class="split-button-group">
66
+ <div class="main-button-wrapper">
67
+ <slot
68
+ name="button"
69
+ {closeDropdown}
70
+ {handleAction}
71
+ selectedLabel={$selectedLabel}
72
+ />
73
+ </div>
74
+
75
+ <button
76
+ {...$trigger}
77
+ use:trigger
78
+ class="trigger style-{style}"
79
+ {disabled}
80
+ aria-label="Open dropdown"
81
+ >
82
+ &#9660;
83
+ </button>
84
+
85
+ {#if $open}
86
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
87
+ <div {...$menu} use:menu on:mousedown|preventDefault class="menu">
88
+ {#each options as item}
89
+ <div
90
+ {...$option({ value: item.value, label: item.title })}
91
+ use:option
92
+ class="option"
93
+ class:option-selected={$isSelected(item.value)}
94
+ >
95
+ {item.title}
96
+ </div>
97
+ {/each}
98
+ </div>
99
+ {/if}
3
100
  </div>
4
101
 
5
102
  <style>
6
- .button-group {
7
- display: flex;
8
- gap: 0;
103
+ .split-button-group {
104
+ display: inline-flex;
9
105
  position: relative;
10
106
  }
107
+
108
+ .main-button-wrapper {
109
+ display: inline-flex;
110
+ }
111
+
112
+ .trigger {
113
+ cursor: pointer;
114
+ border-top-right-radius: var(--radius, 0.25rem);
115
+ border-bottom-right-radius: var(--radius, 0.25rem);
116
+ border-top-left-radius: 0;
117
+ border-bottom-left-radius: 0;
118
+ overflow: hidden;
119
+ padding: 0.25rem 0.5rem;
120
+ display: flex;
121
+ align-items: center;
122
+ justify-content: center;
123
+ min-width: 1.5em;
124
+
125
+ font-family: inherit;
126
+ font-feature-settings: inherit;
127
+ font-variation-settings: inherit;
128
+ font-size: 100%;
129
+ font-weight: inherit;
130
+ line-height: inherit;
131
+ letter-spacing: inherit;
132
+ color: inherit;
133
+ margin: 0;
134
+ text-transform: none;
135
+ background-color: transparent;
136
+ border: 1px solid transparent;
137
+ }
138
+
139
+ .trigger:disabled {
140
+ cursor: default;
141
+ }
142
+
143
+ .trigger:focus {
144
+ outline: var(--focus-outline);
145
+ outline-offset: var(--focus-offset);
146
+ }
147
+
148
+ .trigger.style-normal {
149
+ color: var(--foreground-muted);
150
+ background-color: var(--background-muted);
151
+ border: 1px solid var(--background-soft);
152
+ border-left: none;
153
+ }
154
+
155
+ .trigger.style-normal:hover:not(:disabled) {
156
+ background-color: var(--background-soft);
157
+ }
158
+
159
+ .trigger.style-normal:disabled {
160
+ color: var(--foreground-disabled);
161
+ background-color: var(--background-soft);
162
+ border: 1px solid var(--background-soft);
163
+ border-left: none;
164
+ }
165
+
166
+ .trigger.style-outlined {
167
+ background-color: var(--background-muted);
168
+ border: 1px solid var(--accent);
169
+ border-left: none;
170
+ color: var(--foreground-muted);
171
+ }
172
+
173
+ .trigger.style-outlined:hover:not(:disabled) {
174
+ background-color: var(--accent-soft);
175
+ border-color: var(--accent-muted);
176
+ }
177
+
178
+ .trigger.style-outlined:disabled {
179
+ background-color: var(--background-muted);
180
+ color: var(--foreground-disabled);
181
+ border: 1px solid var(--accent-soft);
182
+ border-left: none;
183
+ }
184
+
185
+ .trigger.style-accept {
186
+ color: var(--foreground);
187
+ background-color: var(--accent);
188
+ border-left: none;
189
+ }
190
+
191
+ .trigger.style-accept:hover:not(:disabled) {
192
+ background-color: var(--accent-soft);
193
+ }
194
+
195
+ .trigger.style-accept:disabled {
196
+ color: var(--foreground-disabled);
197
+ background-color: var(--accent-soft);
198
+ border-left: none;
199
+ }
200
+
201
+ .menu {
202
+ z-index: 40;
203
+ width: -moz-max-content;
204
+ width: max-content;
205
+ min-width: 8em;
206
+ background-color: var(--popover-background);
207
+ color: var(--foreground-muted);
208
+ border: 1px solid var(--foreground-muted);
209
+ border-radius: var(--radius, 0.25rem);
210
+ }
211
+
212
+ .option {
213
+ cursor: pointer;
214
+ padding: 0.5rem;
215
+ /* Cap width here, not on .menu: floating-ui writes an inline
216
+ max-width on the menu element (fitViewport), which would override
217
+ a stylesheet max-width. The menu is width:max-content, so capping
218
+ the options caps the menu's intrinsic width too. */
219
+ max-width: 20em;
220
+ white-space: nowrap;
221
+ overflow: hidden;
222
+ text-overflow: ellipsis;
223
+ }
224
+
225
+ .option:hover,
226
+ .option[data-highlighted] {
227
+ background-color: var(--popover-selection);
228
+ color: var(--foreground);
229
+ }
230
+
231
+ .option-selected {
232
+ background-color: var(--popover-reference);
233
+ }
11
234
  </style>
@@ -1,21 +1,8 @@
1
- export default MoltenPushButtonGroup;
2
- type MoltenPushButtonGroup = SvelteComponent<any, {
3
- [evt: string]: CustomEvent<any>;
4
- }, {
5
- default: {};
6
- }> & {
7
- $$bindings?: string | undefined;
8
- };
9
- declare const MoltenPushButtonGroup: $$__sveltets_2_IsomorphicComponent<any, {
10
- [evt: string]: CustomEvent<any>;
11
- }, {
12
- default: {};
13
- }, {}, string>;
14
1
  interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
15
- new (options: import("svelte").ComponentConstructorOptions<Props>): import("svelte").SvelteComponent<Props, Events, Slots> & {
2
+ new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
16
3
  $$bindings?: Bindings;
17
4
  } & Exports;
18
- (internal: unknown, props: {
5
+ (internal: unknown, props: Props & {
19
6
  $$events?: Events;
20
7
  $$slots?: Slots;
21
8
  }): Exports & {
@@ -24,3 +11,25 @@ interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> =
24
11
  };
25
12
  z_$$bindings?: Bindings;
26
13
  }
14
+ declare const MoltenPushButtonGroup: $$__sveltets_2_IsomorphicComponent<{
15
+ options?: {
16
+ title: string;
17
+ value: any;
18
+ onclick?: (value: any) => void;
19
+ }[];
20
+ style?: "normal" | "outlined" | "accept";
21
+ disabled?: boolean;
22
+ target?: any;
23
+ }, {
24
+ mousedown: MouseEvent;
25
+ } & {
26
+ [evt: string]: CustomEvent<any>;
27
+ }, {
28
+ button: {
29
+ closeDropdown: () => void;
30
+ handleAction: () => void;
31
+ selectedLabel: string;
32
+ };
33
+ }, {}, string>;
34
+ type MoltenPushButtonGroup = InstanceType<typeof MoltenPushButtonGroup>;
35
+ export default MoltenPushButtonGroup;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@intechstudio/grid-uikit",
3
- "version": "1.20260626.1315",
3
+ "version": "1.20260713.1934",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "https://github.com/intechstudio/grid-uikit.git"