contain-css-svelte 1.1.11 → 1.1.13

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.
@@ -0,0 +1,231 @@
1
+ <script lang="ts">import { injectVars } from "../util";
2
+ let { primary = false, warning = false, danger = false, success = false, info = false, type = "button", children, ...restProps } = $props();
3
+ const style = $derived(injectVars(restProps, "mini-button", [
4
+ "bg",
5
+ "fg",
6
+ "padding",
7
+ "width",
8
+ "height",
9
+ ]));
10
+ </script>
11
+
12
+ <button
13
+ {style}
14
+ {type}
15
+ class:primary
16
+ class:warning
17
+ class:danger
18
+ class:success
19
+ class:info
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ </button>
24
+
25
+ <style>/* Warning: because we define a fallback
26
+ media query, the media query can override the container
27
+ if we stack a bunch of these in a row and aren't thoughtful about the order.
28
+ Put min-width queries *after* max-width queries so that smaller
29
+ container queries don't get their styles overridden by large media queries.
30
+ */
31
+ /* Convenience groupings */
32
+ button.primary {
33
+ --link-bg: var(--primary-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
34
+ --link-fg: var(--primary-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
35
+ --_bg-mix-color: var(--primary-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
36
+ --_bg-mix-amount: var(--primary-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
37
+ --_fg-mix-color: var(--primary-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
38
+ --_fg-mix-amount: var(--primary-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
39
+ --_bg-base: var(--primary-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
40
+ --_fg-base: var(--primary-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
41
+ --_background-color: color-mix(
42
+ in srgb,
43
+ var(--_bg-base),
44
+ var(--_bg-mix-color) var(--_bg-mix-amount)
45
+ );
46
+ --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
47
+ background-color: var(--_background-color);
48
+ color: var(--_color);
49
+ }
50
+
51
+ button {
52
+ font-family: var(--mini-button-font-family, var(--button-font-family, var(--ui-font-family, var(--control-font-family, var(--font-family, unset)))));
53
+ text-transform: var(--mini-button-text-transform, var(--button-text-transform, var(--ui-text-transform, var(--control-text-transform, var(--text-transform, unset)))));
54
+ text-decoration: var(--mini-button-text-decoration, var(--button-text-decoration, var(--ui-text-decoration, var(--control-text-decoration, var(--text-decoration, unset)))));
55
+ --_font-size: var(--mini-button-font-size, var(--button-font-size, var(--ui-font-size, var(--control-font-size, var(--font-size, unset)))));
56
+ font-size: var(--_font-size);
57
+ font-weight: var(--mini-button-font-weight, var(--button-font-weight, var(--ui-font-weight, var(--control-font-weight, var(--font-weight, unset)))));
58
+ line-height: var(--mini-button-line-height, var(--button-line-height, var(--ui-line-height, var(--control-line-height, var(--line-height, unset)))));
59
+ letter-spacing: var(--mini-button-letter-spacing, var(--button-letter-spacing, var(--ui-letter-spacing, var(--control-letter-spacing, var(--letter-spacing, unset)))));
60
+ --_margin-top: var(--mini-button-margin, var(--button-margin, var(--ui-margin, var(--control-margin, var(--margin, unset)))));
61
+ --_margin-top: var(--mini-button-margin-top, var(--button-margin-top, var(--ui-margin-top, var(--control-margin-top, var(--margin-top, unset)))));
62
+ margin-top: var(--_margin-top);
63
+ --_margin-bottom: var(--mini-button-margin, var(--button-margin, var(--ui-margin, var(--control-margin, var(--margin, unset)))));
64
+ --_margin-bottom: var(--mini-button-margin-bottom, var(--button-margin-bottom, var(--ui-margin-bottom, var(--control-margin-bottom, var(--margin-bottom, unset)))));
65
+ margin-bottom: var(--_margin-bottom);
66
+ text-indent: var(--mini-button-indent, var(--button-indent, var(--ui-indent, var(--control-indent, var(--indent, unset)))));
67
+ font-variant: var(--mini-button-font-variant, var(--button-font-variant, var(--ui-font-variant, var(--control-font-variant, var(--font-variant, unset)))));
68
+ text-align: var(--mini-button-text-align, var(--button-text-align, var(--ui-text-align, var(--control-text-align, var(--text-align, unset)))));
69
+ --link-bg: var(--mini-button-link-bg, var(--button-link-bg, var(--control-link-bg, var(--secondary-link-bg, inherit))));
70
+ --link-fg: var(--mini-button-link-fg, var(--button-link-fg, var(--control-link-fg, var(--secondary-link-fg, inherit))));
71
+ --_bg-mix-color: var(--mini-button-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--secondary-bg-mix-color, var(--bg-mix-color, transparent)))));
72
+ --_bg-mix-amount: var(--mini-button-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--secondary-bg-mix-amount, var(--bg-mix-amount, 0%)))));
73
+ --_fg-mix-color: var(--mini-button-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--secondary-fg-mix-color, var(--fg-mix-color, transparent)))));
74
+ --_fg-mix-amount: var(--mini-button-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--secondary-fg-mix-amount, var(--fg-mix-amount, 0%)))));
75
+ --_bg-base: var(--mini-button-bg, var(--button-bg, var(--control-bg, var(--secondary-bg, var(--bg, unset)))));
76
+ --_fg-base: var(--mini-button-fg, var(--button-fg, var(--control-fg, var(--secondary-fg, var(--fg, unset)))));
77
+ --_background-color: color-mix(
78
+ in srgb,
79
+ var(--_bg-base),
80
+ var(--_bg-mix-color) var(--_bg-mix-amount)
81
+ );
82
+ --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
83
+ background-color: var(--_background-color);
84
+ color: var(--_color);
85
+ cursor: var(--mini-button-cursor, var(--button-cursor, var(--clickable-cursor, var(--cursor, pointer))));
86
+ transition: filter var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), background-color var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), border-color var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), box-shadow var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), transform var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms))));
87
+ }
88
+
89
+ button:hover {
90
+ filter: var(--mini-button-hover-filter, var(--button-hover-filter, var(--clickable-hover-filter, var(--hover-filter, brightness(1.05)))));
91
+ transform: var(--mini-button-hover-transform, var(--button-hover-transform, var(--clickable-hover-transform, var(--hover-transform, none))));
92
+ background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
93
+ box-shadow: var(--mini-button-hover-box-shadow, var(--button-hover-box-shadow, var(--clickable-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)))));
94
+ }
95
+
96
+ button:active {
97
+ filter: var(--mini-button-active-filter, var(--button-active-filter, var(--clickable-active-filter, var(--active-filter, brightness(0.9)))));
98
+ transform: var(--mini-button-active-transform, var(--button-active-transform, var(--clickable-active-transform, var(--active-transform, none))));
99
+ background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
100
+ box-shadow: var(--mini-button-active-box-shadow, var(--button-active-box-shadow, var(--clickable-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)))));
101
+ }
102
+
103
+ button:disabled {
104
+ cursor: var(--mini-button-disabled-cursor, var(--button-disabled-cursor, var(--clickable-disabled-cursor, var(--disabled-cursor, not-allowed))));
105
+ transform: var(--mini-button-disabled-transform, var(--button-disabled-transform, var(--clickable-disabled-transform, var(--disabled-transform, none))));
106
+ filter: var(--mini-button-disabled-filter, var(--button-disabled-filter, var(--clickable-disabled-filter, var(--disabled-filter, grayscale(0.5)))));
107
+ background-color: color-mix(in oklch, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
108
+ box-shadow: var(--mini-button-disabled-box-shadow, var(--button-disabled-box-shadow, var(--clickable-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)))));
109
+ }
110
+
111
+ button {
112
+ --_box-shadow:
113
+ var(--mini-button-shadow-distance, var(--button-shadow-distance, var(--control-shadow-distance, var(--shadow-distance, var(--space))))) var(--mini-button-shadow-distance, var(--button-shadow-distance, var(--control-shadow-distance, var(--shadow-distance, var(--space))))) var(--mini-button-shadow-blur, var(--button-shadow-blur, var(--control-shadow-blur, var(--shadow-blur, var(--space))))) var(--mini-button-shadow-color, var(--button-shadow-color, var(--control-shadow-color, var(--shadow-color, rgba(127, 127, 127, 0.4)))));
114
+ box-shadow: var(--_box-shadow);
115
+ }
116
+
117
+ button:focus-visible {
118
+ outline: var(--focus-color, -webkit-focus-ring-color) auto 1px;
119
+ outline-offset: var(--focus-outline-offset, 2px);
120
+ box-shadow: var(--focus-ring-box-shadow, 0 0 0 3px var(--focus-shadow-color, rgba(100, 150, 250, 0.5)));
121
+ }
122
+
123
+ button {
124
+ margin: var(--button-margin, var(--control-margin, var(--margin, var(--space))));
125
+ width: var(--mini-button-size, var(--icon-size, 1em));
126
+ height: var(--mini-button-size, var(--icon-size, 1em));
127
+ /* Make sure we don't shrink in a flex container */
128
+ min-width: var(--mini-button-size, var(--icon-size, 1em));
129
+ min-height: var(--mini-button-size, var(--icon-size, 1em));
130
+ border-radius: var(--mini-button-radius, 50%);
131
+ border: var(--mini-button-border, button-border, none);
132
+ display: inline-grid;
133
+ place-content: center;
134
+ line-height: 1;
135
+ flex-shrink: 0; /* Don't shrink any more */
136
+ }
137
+
138
+ button.primary {
139
+ --link-bg: var(--primary-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
140
+ --link-fg: var(--primary-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
141
+ --_bg-mix-color: var(--primary-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
142
+ --_bg-mix-amount: var(--primary-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
143
+ --_fg-mix-color: var(--primary-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
144
+ --_fg-mix-amount: var(--primary-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
145
+ --_bg-base: var(--primary-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
146
+ --_fg-base: var(--primary-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
147
+ --_background-color: color-mix(
148
+ in srgb,
149
+ var(--_bg-base),
150
+ var(--_bg-mix-color) var(--_bg-mix-amount)
151
+ );
152
+ --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
153
+ background-color: var(--_background-color);
154
+ color: var(--_color);
155
+ }
156
+
157
+ button.warning {
158
+ --link-bg: var(--warning-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
159
+ --link-fg: var(--warning-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
160
+ --_bg-mix-color: var(--warning-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
161
+ --_bg-mix-amount: var(--warning-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
162
+ --_fg-mix-color: var(--warning-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
163
+ --_fg-mix-amount: var(--warning-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
164
+ --_bg-base: var(--warning-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
165
+ --_fg-base: var(--warning-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
166
+ --_background-color: color-mix(
167
+ in srgb,
168
+ var(--_bg-base),
169
+ var(--_bg-mix-color) var(--_bg-mix-amount)
170
+ );
171
+ --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
172
+ background-color: var(--_background-color);
173
+ color: var(--_color);
174
+ }
175
+
176
+ button.danger {
177
+ --link-bg: var(--danger-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
178
+ --link-fg: var(--danger-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
179
+ --_bg-mix-color: var(--danger-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
180
+ --_bg-mix-amount: var(--danger-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
181
+ --_fg-mix-color: var(--danger-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
182
+ --_fg-mix-amount: var(--danger-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
183
+ --_bg-base: var(--danger-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
184
+ --_fg-base: var(--danger-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
185
+ --_background-color: color-mix(
186
+ in srgb,
187
+ var(--_bg-base),
188
+ var(--_bg-mix-color) var(--_bg-mix-amount)
189
+ );
190
+ --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
191
+ background-color: var(--_background-color);
192
+ color: var(--_color);
193
+ }
194
+
195
+ button.success {
196
+ --link-bg: var(--success-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
197
+ --link-fg: var(--success-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
198
+ --_bg-mix-color: var(--success-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
199
+ --_bg-mix-amount: var(--success-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
200
+ --_fg-mix-color: var(--success-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
201
+ --_fg-mix-amount: var(--success-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
202
+ --_bg-base: var(--success-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
203
+ --_fg-base: var(--success-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
204
+ --_background-color: color-mix(
205
+ in srgb,
206
+ var(--_bg-base),
207
+ var(--_bg-mix-color) var(--_bg-mix-amount)
208
+ );
209
+ --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
210
+ background-color: var(--_background-color);
211
+ color: var(--_color);
212
+ }
213
+
214
+ button.info {
215
+ --link-bg: var(--info-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
216
+ --link-fg: var(--info-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
217
+ --_bg-mix-color: var(--info-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
218
+ --_bg-mix-amount: var(--info-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
219
+ --_fg-mix-color: var(--info-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
220
+ --_fg-mix-amount: var(--info-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
221
+ --_bg-base: var(--info-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
222
+ --_fg-base: var(--info-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
223
+ --_background-color: color-mix(
224
+ in srgb,
225
+ var(--_bg-base),
226
+ var(--_bg-mix-color) var(--_bg-mix-amount)
227
+ );
228
+ --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
229
+ background-color: var(--_background-color);
230
+ color: var(--_color);
231
+ }</style>
@@ -0,0 +1,14 @@
1
+ import type { HTMLButtonAttributes } from "svelte/elements";
2
+ import type { BaseStyleProps } from "../types";
3
+ type Props = {
4
+ primary?: boolean;
5
+ warning?: boolean;
6
+ danger?: boolean;
7
+ success?: boolean;
8
+ info?: boolean;
9
+ type?: "button" | "submit" | "reset";
10
+ children?: import("svelte").Snippet;
11
+ } & BaseStyleProps & HTMLButtonAttributes;
12
+ declare const CircleButton: import("svelte").Component<Props, {}, "">;
13
+ type CircleButton = ReturnType<typeof CircleButton>;
14
+ export default CircleButton;
@@ -1,231 +1,5 @@
1
- <script lang="ts">import { injectVars } from "../util";
2
- let { primary = false, warning = false, danger = false, success = false, info = false, type = "button", children, ...restProps } = $props();
3
- const style = $derived(injectVars(restProps, "mini-button", [
4
- "bg",
5
- "fg",
6
- "padding",
7
- "width",
8
- "height",
9
- ]));
1
+ <script lang="ts">import CircleButton from "./CircleButton.svelte";
2
+ let props = $props();
10
3
  </script>
11
4
 
12
- <button
13
- {style}
14
- {type}
15
- class:primary
16
- class:warning
17
- class:danger
18
- class:success
19
- class:info
20
- {...restProps}
21
- >
22
- {@render children?.()}
23
- </button>
24
-
25
- <style>/* Warning: because we define a fallback
26
- media query, the media query can override the container
27
- if we stack a bunch of these in a row and aren't thoughtful about the order.
28
- Put min-width queries *after* max-width queries so that smaller
29
- container queries don't get their styles overridden by large media queries.
30
- */
31
- /* Convenience groupings */
32
- button.primary {
33
- --link-bg: var(--primary-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
34
- --link-fg: var(--primary-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
35
- --_bg-mix-color: var(--primary-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
36
- --_bg-mix-amount: var(--primary-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
37
- --_fg-mix-color: var(--primary-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
38
- --_fg-mix-amount: var(--primary-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
39
- --_bg-base: var(--primary-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
40
- --_fg-base: var(--primary-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
41
- --_background-color: color-mix(
42
- in srgb,
43
- var(--_bg-base),
44
- var(--_bg-mix-color) var(--_bg-mix-amount)
45
- );
46
- --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
47
- background-color: var(--_background-color);
48
- color: var(--_color);
49
- }
50
-
51
- button {
52
- font-family: var(--mini-button-font-family, var(--button-font-family, var(--ui-font-family, var(--control-font-family, var(--font-family, unset)))));
53
- text-transform: var(--mini-button-text-transform, var(--button-text-transform, var(--ui-text-transform, var(--control-text-transform, var(--text-transform, unset)))));
54
- text-decoration: var(--mini-button-text-decoration, var(--button-text-decoration, var(--ui-text-decoration, var(--control-text-decoration, var(--text-decoration, unset)))));
55
- --_font-size: var(--mini-button-font-size, var(--button-font-size, var(--ui-font-size, var(--control-font-size, var(--font-size, unset)))));
56
- font-size: var(--_font-size);
57
- font-weight: var(--mini-button-font-weight, var(--button-font-weight, var(--ui-font-weight, var(--control-font-weight, var(--font-weight, unset)))));
58
- line-height: var(--mini-button-line-height, var(--button-line-height, var(--ui-line-height, var(--control-line-height, var(--line-height, unset)))));
59
- letter-spacing: var(--mini-button-letter-spacing, var(--button-letter-spacing, var(--ui-letter-spacing, var(--control-letter-spacing, var(--letter-spacing, unset)))));
60
- --_margin-top: var(--mini-button-margin, var(--button-margin, var(--ui-margin, var(--control-margin, var(--margin, unset)))));
61
- --_margin-top: var(--mini-button-margin-top, var(--button-margin-top, var(--ui-margin-top, var(--control-margin-top, var(--margin-top, unset)))));
62
- margin-top: var(--_margin-top);
63
- --_margin-bottom: var(--mini-button-margin, var(--button-margin, var(--ui-margin, var(--control-margin, var(--margin, unset)))));
64
- --_margin-bottom: var(--mini-button-margin-bottom, var(--button-margin-bottom, var(--ui-margin-bottom, var(--control-margin-bottom, var(--margin-bottom, unset)))));
65
- margin-bottom: var(--_margin-bottom);
66
- text-indent: var(--mini-button-indent, var(--button-indent, var(--ui-indent, var(--control-indent, var(--indent, unset)))));
67
- font-variant: var(--mini-button-font-variant, var(--button-font-variant, var(--ui-font-variant, var(--control-font-variant, var(--font-variant, unset)))));
68
- text-align: var(--mini-button-text-align, var(--button-text-align, var(--ui-text-align, var(--control-text-align, var(--text-align, unset)))));
69
- --link-bg: var(--mini-button-link-bg, var(--button-link-bg, var(--control-link-bg, var(--secondary-link-bg, inherit))));
70
- --link-fg: var(--mini-button-link-fg, var(--button-link-fg, var(--control-link-fg, var(--secondary-link-fg, inherit))));
71
- --_bg-mix-color: var(--mini-button-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--secondary-bg-mix-color, var(--bg-mix-color, transparent)))));
72
- --_bg-mix-amount: var(--mini-button-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--secondary-bg-mix-amount, var(--bg-mix-amount, 0%)))));
73
- --_fg-mix-color: var(--mini-button-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--secondary-fg-mix-color, var(--fg-mix-color, transparent)))));
74
- --_fg-mix-amount: var(--mini-button-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--secondary-fg-mix-amount, var(--fg-mix-amount, 0%)))));
75
- --_bg-base: var(--mini-button-bg, var(--button-bg, var(--control-bg, var(--secondary-bg, var(--bg, unset)))));
76
- --_fg-base: var(--mini-button-fg, var(--button-fg, var(--control-fg, var(--secondary-fg, var(--fg, unset)))));
77
- --_background-color: color-mix(
78
- in srgb,
79
- var(--_bg-base),
80
- var(--_bg-mix-color) var(--_bg-mix-amount)
81
- );
82
- --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
83
- background-color: var(--_background-color);
84
- color: var(--_color);
85
- cursor: var(--mini-button-cursor, var(--button-cursor, var(--clickable-cursor, var(--cursor, pointer))));
86
- transition: filter var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), background-color var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), border-color var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), box-shadow var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms)))), transform var(--mini-button-transition, var(--button-transition, var(--clickable-transition, var(--transition, 300ms))));
87
- }
88
-
89
- button:hover {
90
- filter: var(--mini-button-hover-filter, var(--button-hover-filter, var(--clickable-hover-filter, var(--hover-filter, brightness(1.05)))));
91
- transform: var(--mini-button-hover-transform, var(--button-hover-transform, var(--clickable-hover-transform, var(--hover-transform, none))));
92
- background-color: color-mix(in oklch, var(--_background-color) var(--hover-base-color-percentage, 90%), var(--hover-color-mix, white) calc(100% - var(--hover-base-color-percentage, 90%)));
93
- box-shadow: var(--mini-button-hover-box-shadow, var(--button-hover-box-shadow, var(--clickable-hover-box-shadow, var(--hover-box-shadow, var(--_box-shadow, none)))));
94
- }
95
-
96
- button:active {
97
- filter: var(--mini-button-active-filter, var(--button-active-filter, var(--clickable-active-filter, var(--active-filter, brightness(0.9)))));
98
- transform: var(--mini-button-active-transform, var(--button-active-transform, var(--clickable-active-transform, var(--active-transform, none))));
99
- background-color: color-mix(in oklch, var(--_background-color) var(--active-base-color-percentage, 90%), var(--active-color-mix, black) calc(100% - var(--active-base-color-percentage, 90%)));
100
- box-shadow: var(--mini-button-active-box-shadow, var(--button-active-box-shadow, var(--clickable-active-box-shadow, var(--active-box-shadow, var(--_box-shadow, none)))));
101
- }
102
-
103
- button:disabled {
104
- cursor: var(--mini-button-disabled-cursor, var(--button-disabled-cursor, var(--clickable-disabled-cursor, var(--disabled-cursor, not-allowed))));
105
- transform: var(--mini-button-disabled-transform, var(--button-disabled-transform, var(--clickable-disabled-transform, var(--disabled-transform, none))));
106
- filter: var(--mini-button-disabled-filter, var(--button-disabled-filter, var(--clickable-disabled-filter, var(--disabled-filter, grayscale(0.5)))));
107
- background-color: color-mix(in oklch, var(--_background-color) var(--disabled-base-color-percentage, 50%), var(--disabled-color-mix, gray) calc(100% - var(--disabled-base-color-percentage, 50%)));
108
- box-shadow: var(--mini-button-disabled-box-shadow, var(--button-disabled-box-shadow, var(--clickable-disabled-box-shadow, var(--disabled-box-shadow, var(--_box-shadow, none)))));
109
- }
110
-
111
- button {
112
- --_box-shadow:
113
- var(--mini-button-shadow-distance, var(--button-shadow-distance, var(--control-shadow-distance, var(--shadow-distance, var(--space))))) var(--mini-button-shadow-distance, var(--button-shadow-distance, var(--control-shadow-distance, var(--shadow-distance, var(--space))))) var(--mini-button-shadow-blur, var(--button-shadow-blur, var(--control-shadow-blur, var(--shadow-blur, var(--space))))) var(--mini-button-shadow-color, var(--button-shadow-color, var(--control-shadow-color, var(--shadow-color, rgba(127, 127, 127, 0.4)))));
114
- box-shadow: var(--_box-shadow);
115
- }
116
-
117
- button:focus-visible {
118
- outline: var(--focus-color, -webkit-focus-ring-color) auto 1px;
119
- outline-offset: var(--focus-outline-offset, 2px);
120
- box-shadow: var(--focus-ring-box-shadow, 0 0 0 3px var(--focus-shadow-color, rgba(100, 150, 250, 0.5)));
121
- }
122
-
123
- button {
124
- margin: var(--button-margin, var(--control-margin, var(--margin, var(--space))));
125
- width: var(--mini-button-size, var(--icon-size, 1em));
126
- height: var(--mini-button-size, var(--icon-size, 1em));
127
- /* Make sure we don't shrink in a flex container */
128
- min-width: var(--mini-button-size, var(--icon-size, 1em));
129
- min-height: var(--mini-button-size, var(--icon-size, 1em));
130
- border-radius: var(--mini-button-radius, 50%);
131
- border: var(--mini-button-border, button-border, none);
132
- display: inline-grid;
133
- place-content: center;
134
- line-height: 1;
135
- flex-shrink: 0; /* Don't shrink any more */
136
- }
137
-
138
- button.primary {
139
- --link-bg: var(--primary-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
140
- --link-fg: var(--primary-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
141
- --_bg-mix-color: var(--primary-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
142
- --_bg-mix-amount: var(--primary-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
143
- --_fg-mix-color: var(--primary-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
144
- --_fg-mix-amount: var(--primary-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
145
- --_bg-base: var(--primary-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
146
- --_fg-base: var(--primary-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
147
- --_background-color: color-mix(
148
- in srgb,
149
- var(--_bg-base),
150
- var(--_bg-mix-color) var(--_bg-mix-amount)
151
- );
152
- --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
153
- background-color: var(--_background-color);
154
- color: var(--_color);
155
- }
156
-
157
- button.warning {
158
- --link-bg: var(--warning-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
159
- --link-fg: var(--warning-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
160
- --_bg-mix-color: var(--warning-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
161
- --_bg-mix-amount: var(--warning-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
162
- --_fg-mix-color: var(--warning-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
163
- --_fg-mix-amount: var(--warning-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
164
- --_bg-base: var(--warning-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
165
- --_fg-base: var(--warning-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
166
- --_background-color: color-mix(
167
- in srgb,
168
- var(--_bg-base),
169
- var(--_bg-mix-color) var(--_bg-mix-amount)
170
- );
171
- --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
172
- background-color: var(--_background-color);
173
- color: var(--_color);
174
- }
175
-
176
- button.danger {
177
- --link-bg: var(--danger-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
178
- --link-fg: var(--danger-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
179
- --_bg-mix-color: var(--danger-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
180
- --_bg-mix-amount: var(--danger-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
181
- --_fg-mix-color: var(--danger-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
182
- --_fg-mix-amount: var(--danger-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
183
- --_bg-base: var(--danger-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
184
- --_fg-base: var(--danger-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
185
- --_background-color: color-mix(
186
- in srgb,
187
- var(--_bg-base),
188
- var(--_bg-mix-color) var(--_bg-mix-amount)
189
- );
190
- --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
191
- background-color: var(--_background-color);
192
- color: var(--_color);
193
- }
194
-
195
- button.success {
196
- --link-bg: var(--success-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
197
- --link-fg: var(--success-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
198
- --_bg-mix-color: var(--success-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
199
- --_bg-mix-amount: var(--success-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
200
- --_fg-mix-color: var(--success-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
201
- --_fg-mix-amount: var(--success-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
202
- --_bg-base: var(--success-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
203
- --_fg-base: var(--success-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
204
- --_background-color: color-mix(
205
- in srgb,
206
- var(--_bg-base),
207
- var(--_bg-mix-color) var(--_bg-mix-amount)
208
- );
209
- --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
210
- background-color: var(--_background-color);
211
- color: var(--_color);
212
- }
213
-
214
- button.info {
215
- --link-bg: var(--info-link-bg, var(--button-link-bg, var(--control-link-bg, inherit)));
216
- --link-fg: var(--info-link-fg, var(--button-link-fg, var(--control-link-fg, inherit)));
217
- --_bg-mix-color: var(--info-bg-mix-color, var(--button-bg-mix-color, var(--control-bg-mix-color, var(--bg-mix-color, transparent))));
218
- --_bg-mix-amount: var(--info-bg-mix-amount, var(--button-bg-mix-amount, var(--control-bg-mix-amount, var(--bg-mix-amount, 0%))));
219
- --_fg-mix-color: var(--info-fg-mix-color, var(--button-fg-mix-color, var(--control-fg-mix-color, var(--fg-mix-color, transparent))));
220
- --_fg-mix-amount: var(--info-fg-mix-amount, var(--button-fg-mix-amount, var(--control-fg-mix-amount, var(--fg-mix-amount, 0%))));
221
- --_bg-base: var(--info-bg, var(--button-bg, var(--control-bg, var(--bg, unset))));
222
- --_fg-base: var(--info-fg, var(--button-fg, var(--control-fg, var(--fg, unset))));
223
- --_background-color: color-mix(
224
- in srgb,
225
- var(--_bg-base),
226
- var(--_bg-mix-color) var(--_bg-mix-amount)
227
- );
228
- --_color: color-mix(in srgb, var(--_fg-base), var(--_fg-mix-color) var(--_fg-mix-amount));
229
- background-color: var(--_background-color);
230
- color: var(--_color);
231
- }</style>
5
+ <CircleButton {...props} />
@@ -1,14 +1,3 @@
1
- import type { HTMLButtonAttributes } from "svelte/elements";
2
- import type { BaseStyleProps } from "../types";
3
- type Props = {
4
- primary?: boolean;
5
- warning?: boolean;
6
- danger?: boolean;
7
- success?: boolean;
8
- info?: boolean;
9
- type?: "button" | "submit" | "reset";
10
- children?: import("svelte").Snippet;
11
- } & BaseStyleProps & HTMLButtonAttributes;
12
- declare const MiniButton: import("svelte").Component<Props, {}, "">;
1
+ declare const MiniButton: import("svelte").Component<$$ComponentProps, {}, "">;
13
2
  type MiniButton = ReturnType<typeof MiniButton>;
14
3
  export default MiniButton;
@@ -1,6 +1,6 @@
1
1
  <script lang="ts">import DropdownMenu from "../dropdowns/DropdownMenu.svelte";
2
2
  import { onMount, tick } from "svelte";
3
- let { value = $bindable(), children, "data-audit-action": dropdownAuditAction = null, ...restProps } = $props();
3
+ let { value = $bindable(), children, "data-audit-action": dropdownAuditAction = null, matchMode = "prefix", typeaheadMode = "focus", ...restProps } = $props();
4
4
  let selectElement = $state();
5
5
  let observer;
6
6
  let resizeObserver;
@@ -95,7 +95,11 @@ $effect(() => {
95
95
  {@render children?.()}
96
96
  </select>
97
97
  <div class="dropdown-wrapper" style:--target-width={targetWidth}>
98
- <DropdownMenu triggerAuditAction={dropdownAuditAction}>
98
+ <DropdownMenu
99
+ triggerAuditAction={dropdownAuditAction}
100
+ {matchMode}
101
+ {typeaheadMode}
102
+ >
99
103
  {#snippet label()}
100
104
  <span
101
105
  class="select-dropdown"
@@ -1,8 +1,13 @@
1
1
  import type { HTMLSelectAttributes } from "svelte/elements";
2
+ import type { MatchMode, TypeaheadMode } from "../dropdowns/DropdownMenu.svelte";
2
3
  type Props = {
3
4
  value?: any;
4
5
  children?: import("svelte").Snippet;
5
6
  "data-audit-action"?: string | null;
7
+ /** See {@link MatchMode} on DropdownMenu -- how type-ahead text is compared. */
8
+ matchMode?: MatchMode;
9
+ /** See {@link TypeaheadMode} on DropdownMenu -- focus a match or filter the list. */
10
+ typeaheadMode?: TypeaheadMode;
6
11
  } & HTMLSelectAttributes;
7
12
  declare const Select: import("svelte").Component<Props, {}, "value">;
8
13
  type Select = ReturnType<typeof Select>;
@@ -1,12 +1,12 @@
1
- <script module lang="ts">"use strict";
2
- var idPostfix = 1;
1
+ <script module lang="ts">var idPostfix = 1;
2
+ export {};
3
3
  </script>
4
4
 
5
5
  <script lang="ts">import { cssProperties } from "../cssprops";
6
6
  import MenuList from "../layout/MenuList.svelte";
7
7
  import { injectVars } from "../util";
8
8
  import { onMount } from "svelte";
9
- let { label, children, triggerAuditAction = null, ...props } = $props();
9
+ let { label, children, triggerAuditAction = null, matchMode = "prefix", typeaheadMode = "focus", ...props } = $props();
10
10
  idPostfix++;
11
11
  let id = "contain-dropdown-menu-" + idPostfix;
12
12
  let buttonElement = $state();
@@ -65,48 +65,133 @@ function clearSearch() {
65
65
  clearTimeout(clearTimer);
66
66
  clearTimer = undefined;
67
67
  searchString = "";
68
+ clearFilter();
68
69
  }
69
70
  const timeoutAfterMS = 2500; // 2.5 seconds seems more humane
70
71
  function scheduleSearchClear() {
72
+ // In filter mode the buffer is a live filter, not a transient jump target --
73
+ // auto-clearing it mid-scroll would make the list flicker back to full
74
+ // length. It persists until Escape, close, or Backspace to empty.
75
+ if (typeaheadMode === "filter")
76
+ return;
71
77
  clearTimeout(clearTimer);
72
78
  clearTimer = setTimeout(clearSearch, timeoutAfterMS);
73
79
  }
74
80
  function handleKeystroke(event) {
75
81
  if (event.key == "Backspace" && searchString) {
76
82
  searchString = searchString.slice(0, -1);
83
+ applySearch();
77
84
  scheduleSearchClear();
78
85
  }
79
86
  else if (event.key.length == 1) {
80
87
  if (searchString || event.key != " ") {
81
88
  searchString += event.key;
82
- maybeFocusMatch(searchString);
89
+ applySearch();
83
90
  scheduleSearchClear();
84
91
  }
85
92
  }
86
- else {
93
+ else if (event.key === "Escape") {
94
+ clearSearch();
95
+ popoverDiv?.hidePopover();
96
+ }
97
+ else if (event.key === "ArrowDown" || event.key === "ArrowUp") {
98
+ event.preventDefault(); // Prevent default to stop scrolling the page
99
+ // In filter mode the buffer stays live so arrow keys (and Tab) cycle
100
+ // through the *filtered* rows -- type a few letters, then arrow down to
101
+ // the one you saw. In focus mode a navigation key ends the type-ahead.
102
+ if (typeaheadMode !== "filter")
103
+ clearSearch();
104
+ navigateMenu(event.key);
105
+ }
106
+ else if (typeaheadMode !== "filter") {
107
+ // Tab, Enter, Home/End, etc. -- end a focus-mode type-ahead session.
108
+ // Filter mode keeps the filter until Escape, close, or Backspace-to-empty.
87
109
  clearSearch();
88
- if (event.key === "Escape") {
89
- popoverDiv?.hidePopover();
110
+ }
111
+ }
112
+ /** Route the current buffer to whichever behavior this menu is configured for. */
113
+ function applySearch() {
114
+ if (typeaheadMode === "filter") {
115
+ applyFilter(searchString);
116
+ }
117
+ if (!searchString)
118
+ return;
119
+ const matched = maybeFocusMatch(searchString);
120
+ // In filter mode a filtered-out item may have been holding focus; if nothing
121
+ // matched, park focus on the trigger so keystrokes still reach this <nav>
122
+ // (Backspace to recover, Escape to close).
123
+ if (!matched && typeaheadMode === "filter")
124
+ buttonElement?.focus();
125
+ }
126
+ /** Does `text` satisfy `query` under the active {@link matchMode}? */
127
+ function textMatches(text, query) {
128
+ if (!query)
129
+ return true;
130
+ const haystack = text.toLowerCase();
131
+ const needle = query.toLowerCase();
132
+ if (matchMode === "substring")
133
+ return haystack.includes(needle);
134
+ if (matchMode === "word")
135
+ return haystack.split(/\s+/).some((word) => word.startsWith(needle));
136
+ return haystack.startsWith(needle); // "prefix"
137
+ }
138
+ function getFocusableItems(visibleOnly = false) {
139
+ if (!dropdownContentElement)
140
+ return [];
141
+ let items = Array.from(dropdownContentElement.querySelectorAll("button, a, [tabindex]:not([tabindex='-1'])"));
142
+ if (visibleOnly)
143
+ items = items.filter((el) => el.closest("[hidden]") === null);
144
+ return items;
145
+ }
146
+ /** The row we hide/show for a given item -- its wrapping <li>, or the item. */
147
+ function itemRow(el) {
148
+ return el.closest("li") ?? el;
149
+ }
150
+ function applyFilter(query) {
151
+ if (!dropdownContentElement)
152
+ return;
153
+ if (!query) {
154
+ clearFilter();
155
+ return;
156
+ }
157
+ for (const el of getFocusableItems()) {
158
+ const row = itemRow(el);
159
+ if (textMatches(el.textContent ?? "", query)) {
160
+ if (row.dataset.typeaheadFiltered) {
161
+ delete row.dataset.typeaheadFiltered;
162
+ row.hidden = false;
163
+ }
90
164
  }
91
- else if (event.key === "ArrowDown" || event.key === "ArrowUp") {
92
- event.preventDefault(); // Prevent default to stop scrolling the page
93
- navigateMenu(event.key);
165
+ else if (!row.hidden) {
166
+ row.hidden = true;
167
+ row.dataset.typeaheadFiltered = "true";
94
168
  }
95
169
  }
170
+ // The popover just changed height; keep it anchored under the trigger.
171
+ computePosition();
96
172
  }
97
- function maybeFocusMatch(searchString) {
173
+ /** Undo {@link applyFilter}, leaving any consumer-set `hidden` rows alone. */
174
+ function clearFilter() {
98
175
  if (!dropdownContentElement)
99
176
  return;
100
- let focusableItems = dropdownContentElement.querySelectorAll("a,button,[tabindex]");
101
- for (let element of focusableItems) {
102
- if (element.textContent &&
103
- element.textContent.toLowerCase().startsWith(searchString.toLowerCase())) {
177
+ const hiddenRows = dropdownContentElement.querySelectorAll("[data-typeahead-filtered]");
178
+ for (const row of hiddenRows) {
179
+ delete row.dataset.typeaheadFiltered;
180
+ row.hidden = false;
181
+ }
182
+ if (hiddenRows.length)
183
+ computePosition();
184
+ }
185
+ function maybeFocusMatch(searchString) {
186
+ for (const element of getFocusableItems(true)) {
187
+ if (element.textContent && textMatches(element.textContent, searchString)) {
104
188
  if (element.focus) {
105
189
  element.focus();
106
- return;
190
+ return true;
107
191
  }
108
192
  }
109
193
  }
194
+ return false;
110
195
  }
111
196
  function navigateMenu(direction) {
112
197
  if (!popoverDiv?.matches(":popover-open") && buttonElement) {
@@ -115,7 +200,7 @@ function navigateMenu(direction) {
115
200
  }
116
201
  if (!dropdownContentElement)
117
202
  return;
118
- const focusableItems = Array.from(dropdownContentElement.querySelectorAll("button, a, [tabindex]:not([tabindex='-1'])"));
203
+ const focusableItems = getFocusableItems(true);
119
204
  let currentIndex = focusableItems.findIndex((item) => item === document.activeElement);
120
205
  if (direction === "ArrowDown") {
121
206
  currentIndex = (currentIndex + 1) % focusableItems.length;
@@ -172,7 +257,9 @@ let popoverDiv = $state();
172
257
  style:max-height="{dropdownMaxHeight}px"
173
258
  >
174
259
  {#if searchString}
175
- <div class="search-hint" aria-hidden="true">{searchString}</div>
260
+ <div class="search-hint-wrapper">
261
+ <div class="search-hint" aria-hidden="true">{searchString}</div>
262
+ </div>
176
263
  {/if}
177
264
  <!-- svelte-ignore a11y_no_static_element_interactions -->
178
265
  <div
@@ -434,12 +521,19 @@ button {
434
521
  overflow: hidden;
435
522
  }
436
523
 
524
+ .search-hint-wrapper {
525
+ position: sticky;
526
+ top: 0;
527
+ right: 0;
528
+ height: 0;
529
+ }
530
+
437
531
  .search-hint {
438
- position: absolute;
439
- top: var(--search-hint-offset, 4px);
440
- right: var(--search-hint-offset, 4px);
441
532
  z-index: 2;
533
+ position: absolute;
534
+ right: 0;
442
535
  pointer-events: none;
536
+ width: fit-content;
443
537
  max-width: calc(100% - 2 * var(--search-hint-offset, 4px));
444
538
  --link-bg: var(--search-hint-link-bg, var(--tag-link-bg, var(--secondary-link-bg, inherit)));
445
539
  --link-fg: var(--search-hint-link-fg, var(--tag-link-fg, var(--secondary-link-fg, inherit)));
@@ -1,3 +1,19 @@
1
+ /**
2
+ * How the type-ahead search buffer is compared against each item's text.
3
+ * - "prefix" : item text must start with the query (default, classic
4
+ * <select> behavior)
5
+ * - "word" : any whitespace-delimited word in the item must start with
6
+ * the query -- typing "Boo" matches "Foo Boo Baz"
7
+ * - "substring" : query may appear anywhere in the item text
8
+ */
9
+ export type MatchMode = "prefix" | "word" | "substring";
10
+ /**
11
+ * What a type-ahead match does:
12
+ * - "focus" : move focus to the first matching item (default)
13
+ * - "filter" : hide non-matching items so the list shrinks as you type;
14
+ * focus follows the first remaining match
15
+ */
16
+ export type TypeaheadMode = "focus" | "filter";
1
17
  import type { Snippet } from "svelte";
2
18
  import type { DropdownMenuStyleProps } from "../types";
3
19
  import type { HTMLAttributes } from "svelte/elements";
@@ -5,6 +21,8 @@ type Props = {
5
21
  label?: Snippet;
6
22
  children?: Snippet;
7
23
  triggerAuditAction?: string | null;
24
+ matchMode?: MatchMode;
25
+ typeaheadMode?: TypeaheadMode;
8
26
  } & DropdownMenuStyleProps & HTMLAttributes<HTMLDivElement>;
9
27
  declare const DropdownMenu: import("svelte").Component<Props, {}, "">;
10
28
  type DropdownMenu = ReturnType<typeof DropdownMenu>;
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ import Card from "./Card.svelte";
3
3
  import Button from "./controls/Button.svelte";
4
4
  import ButtonLink from "./controls/ButtonLink.svelte";
5
5
  import Checkbox from "./controls/Checkbox.svelte";
6
+ import CircleButton from "./controls/CircleButton.svelte";
6
7
  import Input from "./controls/Input.svelte";
7
8
  import MiniButton from "./controls/MiniButton.svelte";
8
9
  import RadioButton from "./controls/RadioButton.svelte";
@@ -48,7 +49,7 @@ export type { BaseStyleProps, ContainerStyleProps, BarStyleProps, MenuStyleProps
48
49
  export { Tag };
49
50
  export { Hero };
50
51
  export { TabItem };
51
- export { Button, ButtonLink, Checkbox, Input, Slider, Toggle, RadioButton, MiniButton, Select, Option, };
52
+ export { Button, ButtonLink, CircleButton, Checkbox, Input, Slider, Toggle, RadioButton, MiniButton, Select, Option, };
52
53
  export { Bar, ColumnContainer, Container, GridLayout, GridRow, Inline, MenuList, Page, ResponsiveText, RowContainer, Stack, TabBar, };
53
54
  export { TextLayout, Code, Accordion };
54
55
  export { Card, Tile, Form, FormItem, FormProvider, Fieldset };
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ import Card from "./Card.svelte";
4
4
  import Button from "./controls/Button.svelte";
5
5
  import ButtonLink from "./controls/ButtonLink.svelte";
6
6
  import Checkbox from "./controls/Checkbox.svelte";
7
+ import CircleButton from "./controls/CircleButton.svelte";
7
8
  import Input from "./controls/Input.svelte";
8
9
  import MiniButton from "./controls/MiniButton.svelte";
9
10
  import RadioButton from "./controls/RadioButton.svelte";
@@ -48,7 +49,7 @@ import Tag from "./misc/Tag.svelte";
48
49
  export { Tag };
49
50
  export { Hero };
50
51
  export { TabItem };
51
- export { Button, ButtonLink, Checkbox, Input, Slider, Toggle, RadioButton, MiniButton, Select, Option, };
52
+ export { Button, ButtonLink, CircleButton, Checkbox, Input, Slider, Toggle, RadioButton, MiniButton, Select, Option, };
52
53
  export { Bar, ColumnContainer, Container, GridLayout, GridRow, Inline, MenuList, Page, ResponsiveText, RowContainer, Stack, TabBar, };
53
54
  export { TextLayout, Code, Accordion };
54
55
  export { Card, Tile, Form, FormItem, FormProvider, Fieldset };
@@ -154,7 +154,7 @@ const style = $derived(injectVars(restProps, "menu", [
154
154
 
155
155
  .menu :global(a), .menu :global(button), .menu :global(input[type="submit"]), .menu :global(.button) {
156
156
  display: flex;
157
- justify-content: var(--menu-item-justify, center);
157
+ justify-content: var(--menu-item-justify, start);
158
158
  align-items: var(--menu-item-align, center);
159
159
  width: var(--menu-item-width, 100%);
160
160
  height: var(--menu-item-height);
@@ -336,6 +336,17 @@ a {
336
336
  --material-color-grey-700: #616161;
337
337
  --material-color-grey-800: #424242;
338
338
  --material-color-grey-900: #212121;
339
+ --material-color-gray: var(--material-color-grey);
340
+ --material-color-gray-50: var(--material-color-grey-50);
341
+ --material-color-gray-100: var(--material-color-grey-100);
342
+ --material-color-gray-200: var(--material-color-grey-200);
343
+ --material-color-gray-300: var(--material-color-grey-300);
344
+ --material-color-gray-400: var(--material-color-grey-400);
345
+ --material-color-gray-500: var(--material-color-grey-500);
346
+ --material-color-gray-600: var(--material-color-grey-600);
347
+ --material-color-gray-700: var(--material-color-grey-700);
348
+ --material-color-gray-800: var(--material-color-grey-800);
349
+ --material-color-gray-900: var(--material-color-grey-900);
339
350
 
340
351
  --material-color-blue-grey: #607d8b;
341
352
  --material-color-blue-grey-50: #eceff1;
@@ -348,6 +359,17 @@ a {
348
359
  --material-color-blue-grey-700: #455a64;
349
360
  --material-color-blue-grey-800: #37474f;
350
361
  --material-color-blue-grey-900: #263238;
362
+ --material-color-blue-gray: var(--material-color-blue-grey);
363
+ --material-color-blue-gray-50: var(--material-color-blue-grey-50);
364
+ --material-color-blue-gray-100: var(--material-color-blue-grey-100);
365
+ --material-color-blue-gray-200: var(--material-color-blue-grey-200);
366
+ --material-color-blue-gray-300: var(--material-color-blue-grey-300);
367
+ --material-color-blue-gray-400: var(--material-color-blue-grey-400);
368
+ --material-color-blue-gray-500: var(--material-color-blue-grey-500);
369
+ --material-color-blue-gray-600: var(--material-color-blue-grey-600);
370
+ --material-color-blue-gray-700: var(--material-color-blue-grey-700);
371
+ --material-color-blue-gray-800: var(--material-color-blue-grey-800);
372
+ --material-color-blue-gray-900: var(--material-color-blue-grey-900);
351
373
  }
352
374
 
353
375
  :root {
@@ -359,6 +359,17 @@ a {
359
359
  --material-color-grey-700: #616161;
360
360
  --material-color-grey-800: #424242;
361
361
  --material-color-grey-900: #212121;
362
+ --material-color-gray: var(--material-color-grey);
363
+ --material-color-gray-50: var(--material-color-grey-50);
364
+ --material-color-gray-100: var(--material-color-grey-100);
365
+ --material-color-gray-200: var(--material-color-grey-200);
366
+ --material-color-gray-300: var(--material-color-grey-300);
367
+ --material-color-gray-400: var(--material-color-grey-400);
368
+ --material-color-gray-500: var(--material-color-grey-500);
369
+ --material-color-gray-600: var(--material-color-grey-600);
370
+ --material-color-gray-700: var(--material-color-grey-700);
371
+ --material-color-gray-800: var(--material-color-grey-800);
372
+ --material-color-gray-900: var(--material-color-grey-900);
362
373
 
363
374
  --material-color-blue-grey: #607d8b;
364
375
  --material-color-blue-grey-50: #eceff1;
@@ -371,6 +382,17 @@ a {
371
382
  --material-color-blue-grey-700: #455a64;
372
383
  --material-color-blue-grey-800: #37474f;
373
384
  --material-color-blue-grey-900: #263238;
385
+ --material-color-blue-gray: var(--material-color-blue-grey);
386
+ --material-color-blue-gray-50: var(--material-color-blue-grey-50);
387
+ --material-color-blue-gray-100: var(--material-color-blue-grey-100);
388
+ --material-color-blue-gray-200: var(--material-color-blue-grey-200);
389
+ --material-color-blue-gray-300: var(--material-color-blue-grey-300);
390
+ --material-color-blue-gray-400: var(--material-color-blue-grey-400);
391
+ --material-color-blue-gray-500: var(--material-color-blue-grey-500);
392
+ --material-color-blue-gray-600: var(--material-color-blue-grey-600);
393
+ --material-color-blue-gray-700: var(--material-color-blue-grey-700);
394
+ --material-color-blue-gray-800: var(--material-color-blue-grey-800);
395
+ --material-color-blue-gray-900: var(--material-color-blue-grey-900);
374
396
  }
375
397
  :root {
376
398
  --material-color-red-light: var(--material-color-red-100);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contain-css-svelte",
3
- "version": "1.1.11",
3
+ "version": "1.1.13",
4
4
  "license": "MIT",
5
5
  "scripts": {
6
6
  "capture:review": "node scripts/capture-review.mjs",