@ibobbyts/svelte-ui-utils 0.5.2 → 0.5.4
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.
- package/README.md +26 -1
- package/dist/dropdown/Dropdown.svelte +14 -5
- package/dist/dropdown/Dropdown.svelte.d.ts +2 -1
- package/dist/dropdown/Dropdown.svelte.d.ts.map +1 -1
- package/dist/dropdown/DropdownMultiSelect.svelte +4 -1
- package/dist/dropdown/DropdownMultiSelect.svelte.d.ts +2 -1
- package/dist/dropdown/DropdownMultiSelect.svelte.d.ts.map +1 -1
- package/dist/dropdown/index.d.ts +1 -1
- package/dist/dropdown/index.d.ts.map +1 -1
- package/dist/dropdown/types.d.ts +6 -0
- package/dist/dropdown/types.d.ts.map +1 -1
- package/dist/style.css +91 -25
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -316,7 +316,11 @@ boundary (the bundled `Pagination` does this for its numeric page size). Use
|
|
|
316
316
|
pagination bars. The expanded menu shares the trigger's left edge by default;
|
|
317
317
|
use `menuAlign="right"` to align their right edges instead. `fitContent` sizes
|
|
318
318
|
the menu to its longest option while keeping the selected edge aligned.
|
|
319
|
-
`DataTable` uses this same component for its page-size picker.
|
|
319
|
+
`DataTable` uses this same component for its page-size picker. A trigger
|
|
320
|
+
stretched taller than its content (for example filling a tall table cell)
|
|
321
|
+
centers its collapsed label by default; `verticalAlign="start"` or `"end"`
|
|
322
|
+
pins the label and chevron to the top or bottom edge instead, keeping a
|
|
323
|
+
minimal vertical padding so the content never touches the button border.
|
|
320
324
|
|
|
321
325
|
Set `search={true}` with `loadOptions` to load remote options as the user
|
|
322
326
|
types. The default `inputStyle="dropdown"` keeps the search field inside the
|
|
@@ -890,6 +894,27 @@ inside a theme root:
|
|
|
890
894
|
}
|
|
891
895
|
```
|
|
892
896
|
|
|
897
|
+
### Overlay surface tokens
|
|
898
|
+
|
|
899
|
+
Dropdown menus render as floating overlays: they step the page background up
|
|
900
|
+
(`--suu-color-elevated`, derived from the surface/bg palette) and lift off the
|
|
901
|
+
page with `--suu-shadow-overlay` (a deep shadow plus a hairline ring so the
|
|
902
|
+
outline stays readable over host grid lines). Both resolve against the current
|
|
903
|
+
theme palette automatically.
|
|
904
|
+
|
|
905
|
+
Inside the menu, row semantics come from `--suu-dropdown-*` tokens declared on
|
|
906
|
+
`.suu-dropdown`: `--suu-dropdown-option-separator` (faint line between
|
|
907
|
+
options), `--suu-dropdown-group-border` / `--suu-dropdown-group-bg` /
|
|
908
|
+
`--suu-dropdown-group-text` (the section header band), and
|
|
909
|
+
`--suu-dropdown-option-hover-bg` / `--suu-dropdown-option-selected-bg` /
|
|
910
|
+
`--suu-dropdown-option-selected-hover-bg`. They are palette-derived color
|
|
911
|
+
mixes, so light and dark themes keep the same hierarchy: panel frame > group
|
|
912
|
+
band boundary > option separator, and selected > hover. Only override them for
|
|
913
|
+
a deliberately different overlay treatment.
|
|
914
|
+
|
|
915
|
+
下拉选项默认最小行高为 36px,分组标题为 32px;长文本仍可撑高。
|
|
916
|
+
分组通过中性底色、加粗标题和组内选项缩进区分,未分组的选项不缩进。
|
|
917
|
+
|
|
893
918
|
### Corner-radius tokens
|
|
894
919
|
|
|
895
920
|
All non-zero component corner radii come from the token definitions in
|
|
@@ -24,7 +24,8 @@
|
|
|
24
24
|
DropdownSearchChangeHandler,
|
|
25
25
|
DropdownSelection,
|
|
26
26
|
DropdownTriggerClickHandler,
|
|
27
|
-
DropdownValue
|
|
27
|
+
DropdownValue,
|
|
28
|
+
DropdownVerticalAlign
|
|
28
29
|
} from './types.js';
|
|
29
30
|
|
|
30
31
|
export let id: string | undefined = undefined;
|
|
@@ -50,6 +51,9 @@
|
|
|
50
51
|
export let ariaLabel: string | undefined = undefined;
|
|
51
52
|
export let placement: DropdownPlacement = 'auto';
|
|
52
53
|
export let menuAlign: DropdownMenuAlign = 'left';
|
|
54
|
+
// Center is the historical layout; the modifier classes only exist for the
|
|
55
|
+
// non-default values so existing consumers never see a class change.
|
|
56
|
+
export let verticalAlign: DropdownVerticalAlign = 'center';
|
|
53
57
|
export let fitViewport = true;
|
|
54
58
|
export let fitContent = true;
|
|
55
59
|
export let disabled = false;
|
|
@@ -65,7 +69,11 @@
|
|
|
65
69
|
export let onTriggerClick: DropdownTriggerClickHandler | undefined = undefined;
|
|
66
70
|
|
|
67
71
|
const viewportMargin = 20;
|
|
68
|
-
const menuGap =
|
|
72
|
+
const menuGap = 4;
|
|
73
|
+
// The menu overhangs the trigger horizontally so its edges break from the
|
|
74
|
+
// host layout's lines (table column borders, adjacent inputs) and read as an
|
|
75
|
+
// independent floating layer instead of a continuation of the grid.
|
|
76
|
+
const menuOutset = 4;
|
|
69
77
|
const instanceId = ++dropdownInstanceCount;
|
|
70
78
|
|
|
71
79
|
let open = false;
|
|
@@ -783,12 +791,12 @@
|
|
|
783
791
|
)}px`;
|
|
784
792
|
if (menuAlign === 'right') {
|
|
785
793
|
portalMenuLeft = undefined;
|
|
786
|
-
portalMenuRight = `${Math.round(window.innerWidth - rect.right)}px`;
|
|
794
|
+
portalMenuRight = `${Math.max(0, Math.round(window.innerWidth - rect.right - menuOutset))}px`;
|
|
787
795
|
} else {
|
|
788
|
-
portalMenuLeft = `${Math.round(rect.left)}px`;
|
|
796
|
+
portalMenuLeft = `${Math.max(0, Math.round(rect.left - menuOutset))}px`;
|
|
789
797
|
portalMenuRight = undefined;
|
|
790
798
|
}
|
|
791
|
-
portalMenuWidth = `${Math.round(rect.width)}px`;
|
|
799
|
+
portalMenuWidth = `${Math.round(rect.width + menuOutset * 2)}px`;
|
|
792
800
|
}
|
|
793
801
|
|
|
794
802
|
function portalMenu(node: HTMLDivElement, enabled: boolean) {
|
|
@@ -898,6 +906,7 @@
|
|
|
898
906
|
width !== undefined || minWidth !== undefined || maxWidth !== undefined
|
|
899
907
|
? 'suu-dropdown--sized'
|
|
900
908
|
: '',
|
|
909
|
+
verticalAlign !== 'center' ? `suu-dropdown--valign-${verticalAlign}` : '',
|
|
901
910
|
className ?? ''
|
|
902
911
|
].filter(Boolean).join(' ')}
|
|
903
912
|
style:--suu-dropdown-panel-max-height={viewportPanelMaxHeight}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type UiLanguage } from '../i18n.js';
|
|
2
|
-
import type { DropdownInputStyle, DropdownItemLabelGetter, DropdownLoadOptions, DropdownMenuAlign, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownSelectionChangeHandler, DropdownSearchChangeHandler, DropdownSelection, DropdownTriggerClickHandler } from './types.js';
|
|
2
|
+
import type { DropdownInputStyle, DropdownItemLabelGetter, DropdownLoadOptions, DropdownMenuAlign, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownSelectionChangeHandler, DropdownSearchChangeHandler, DropdownSelection, DropdownTriggerClickHandler, DropdownVerticalAlign } from './types.js';
|
|
3
3
|
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> {
|
|
4
4
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
5
5
|
$$bindings?: Bindings;
|
|
@@ -36,6 +36,7 @@ declare const Dropdown: $$__sveltets_2_IsomorphicComponent<{
|
|
|
36
36
|
ariaLabel?: string | undefined;
|
|
37
37
|
placement?: DropdownPlacement;
|
|
38
38
|
menuAlign?: DropdownMenuAlign;
|
|
39
|
+
verticalAlign?: DropdownVerticalAlign;
|
|
39
40
|
fitViewport?: boolean;
|
|
40
41
|
fitContent?: boolean;
|
|
41
42
|
disabled?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Dropdown.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/Dropdown.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAER,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EAGnB,iBAAiB,EAGjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,2BAA2B,EAC3B,iBAAiB,EACjB,2BAA2B,
|
|
1
|
+
{"version":3,"file":"Dropdown.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/Dropdown.svelte.ts"],"names":[],"mappings":"AAOA,OAAO,EAAiB,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAC5D,OAAO,KAAK,EAER,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EAGnB,iBAAiB,EAGjB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,2BAA2B,EAC3B,iBAAiB,EACjB,2BAA2B,EAE3B,qBAAqB,EACtB,MAAM,YAAY,CAAC;AA09BtB,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,QAAQ;SAXu5B,MAAM,GAAG,SAAS;YAAU,iBAAiB;;cAA8C,cAAc,EAAE;mBAAiB,mBAAmB,EAAE,GAAG,SAAS;IAClkC,sFAAsF,mBAAkB,cAAc,EAAE;+BAA6B,MAAM,GAAG,OAAO,GAAG,MAAM;;iBAAuC,kBAAkB;mBAAiB,uBAAuB;kBAAgB,mBAAmB,GAAG,SAAS;;;wBAAoG,MAAM,GAAG,SAAS;kBAAgB,MAAM,GAAG,SAAS;eAAa,UAAU;kBAAgB,MAAM,GAAG,SAAS;oBAAkB,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;gBAAc,iBAAiB;gBAAc,iBAAiB;oBAAkB,qBAAqB;;;;WAAuG,MAAM,GAAG,SAAS;;YAAsC,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;;eAAqC,8BAA8B,GAAG,SAAS;qBAAmB,2BAA2B,GAAG,SAAS;qBAAmB,2BAA2B,GAAG,SAAS;;;;;kBAU7kC,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
DropdownOption,
|
|
10
10
|
DropdownOptionGroup,
|
|
11
11
|
DropdownPlacement,
|
|
12
|
-
DropdownTriggerClickHandler
|
|
12
|
+
DropdownTriggerClickHandler,
|
|
13
|
+
DropdownVerticalAlign
|
|
13
14
|
} from './types.js';
|
|
14
15
|
|
|
15
16
|
export let id: string | undefined = undefined;
|
|
@@ -21,6 +22,7 @@
|
|
|
21
22
|
export let ariaLabel: string | undefined = undefined;
|
|
22
23
|
export let placement: DropdownPlacement = 'auto';
|
|
23
24
|
export let menuAlign: DropdownMenuAlign = 'left';
|
|
25
|
+
export let verticalAlign: DropdownVerticalAlign = 'center';
|
|
24
26
|
export let fitViewport = true;
|
|
25
27
|
export let fitContent = true;
|
|
26
28
|
export let disabled = false;
|
|
@@ -44,6 +46,7 @@
|
|
|
44
46
|
{ariaLabel}
|
|
45
47
|
{placement}
|
|
46
48
|
{menuAlign}
|
|
49
|
+
{verticalAlign}
|
|
47
50
|
{fitViewport}
|
|
48
51
|
{fitContent}
|
|
49
52
|
{disabled}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DropdownMenuAlign, DropdownMultiChangeHandler, DropdownMultiValue, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownTriggerClickHandler } from './types.js';
|
|
1
|
+
import type { DropdownMenuAlign, DropdownMultiChangeHandler, DropdownMultiValue, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownTriggerClickHandler, DropdownVerticalAlign } from './types.js';
|
|
2
2
|
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> {
|
|
3
3
|
new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
|
|
4
4
|
$$bindings?: Bindings;
|
|
@@ -22,6 +22,7 @@ declare const DropdownMultiSelect: $$__sveltets_2_IsomorphicComponent<{
|
|
|
22
22
|
ariaLabel?: string | undefined;
|
|
23
23
|
placement?: DropdownPlacement;
|
|
24
24
|
menuAlign?: DropdownMenuAlign;
|
|
25
|
+
verticalAlign?: DropdownVerticalAlign;
|
|
25
26
|
fitViewport?: boolean;
|
|
26
27
|
fitContent?: boolean;
|
|
27
28
|
disabled?: boolean;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DropdownMultiSelect.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/DropdownMultiSelect.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,
|
|
1
|
+
{"version":3,"file":"DropdownMultiSelect.svelte.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/DropdownMultiSelect.svelte.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACR,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,2BAA2B,EAC3B,qBAAqB,EACtB,MAAM,YAAY,CAAC;AAkCtB,UAAU,kCAAkC,CAAC,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,MAAM,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,KAAK,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,GAAG,EAAE,EAAE,QAAQ,GAAG,MAAM;IACpM,KAAK,OAAO,EAAE,OAAO,QAAQ,EAAE,2BAA2B,CAAC,KAAK,CAAC,GAAG,OAAO,QAAQ,EAAE,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,GAAG;QAAE,UAAU,CAAC,EAAE,QAAQ,CAAA;KAAE,GAAG,OAAO,CAAC;IACjK,CAAC,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,KAAK,CAAA;KAAC,GAAG,OAAO,GAAG;QAAE,IAAI,CAAC,EAAE,GAAG,CAAC;QAAC,GAAG,CAAC,EAAE,GAAG,CAAA;KAAE,CAAC;IAC9G,YAAY,CAAC,EAAE,QAAQ,CAAC;CAC3B;AAKD,QAAA,MAAM,mBAAmB;SAVoe,MAAM,GAAG,SAAS;YAAU,kBAAkB;cAAY,cAAc,EAAE;mBAAiB,mBAAmB,EAAE,GAAG,SAAS;sBAAoB,cAAc,EAAE;+BAA6B,MAAM,GAAG,OAAO,GAAG,MAAM;gBAAc,MAAM,GAAG,SAAS;gBAAc,iBAAiB;gBAAc,iBAAiB;oBAAkB,qBAAqB;;;;YAAwG,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;;eAAqC,0BAA0B,GAAG,SAAS;qBAAmB,2BAA2B,GAAG,SAAS;;;kBAU7kC,CAAC;AACvF,KAAK,mBAAmB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,eAAe,mBAAmB,CAAC"}
|
package/dist/dropdown/index.d.ts
CHANGED
|
@@ -3,5 +3,5 @@ export { default as DropdownMultiSelect } from './DropdownMultiSelect.svelte';
|
|
|
3
3
|
export { createFetchLoadOptions, createLocalLoadOptions } from './load-options.js';
|
|
4
4
|
export type { FetchLoadOptionsConfig, LocalLoadOptionsConfig, LocalLoadOptionsSource } from './load-options.js';
|
|
5
5
|
export { toMultiSelection, toSingleSelection } from './selection.js';
|
|
6
|
-
export type { DropdownChangeHandler, DropdownInputStyle, DropdownItemLabelGetter, DropdownLoadContext, DropdownLoadOptions, DropdownLoadOptionsResult, DropdownLoadStatus, DropdownMenuAlign, DropdownMultiChangeHandler, DropdownMultiValue, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownSelectionChangeHandler, DropdownSearchChangeHandler, DropdownSelection, DropdownTriggerClickHandler, DropdownValue } from './types.js';
|
|
6
|
+
export type { DropdownChangeHandler, DropdownInputStyle, DropdownItemLabelGetter, DropdownLoadContext, DropdownLoadOptions, DropdownLoadOptionsResult, DropdownLoadStatus, DropdownMenuAlign, DropdownMultiChangeHandler, DropdownMultiValue, DropdownOption, DropdownOptionGroup, DropdownPlacement, DropdownSelectionChangeHandler, DropdownSearchChangeHandler, DropdownSelection, DropdownTriggerClickHandler, DropdownValue, DropdownVerticalAlign } from './types.js';
|
|
7
7
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACrE,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,2BAA2B,EAC3B,iBAAiB,EACjB,2BAA2B,EAC3B,aAAa,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,EAAE,OAAO,IAAI,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAC9E,OAAO,EAAE,sBAAsB,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AACnF,YAAY,EACV,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACrE,YAAY,EACV,qBAAqB,EACrB,kBAAkB,EAClB,uBAAuB,EACvB,mBAAmB,EACnB,mBAAmB,EACnB,yBAAyB,EACzB,kBAAkB,EAClB,iBAAiB,EACjB,0BAA0B,EAC1B,kBAAkB,EAClB,cAAc,EACd,mBAAmB,EACnB,iBAAiB,EACjB,8BAA8B,EAC9B,2BAA2B,EAC3B,iBAAiB,EACjB,2BAA2B,EAC3B,aAAa,EACb,qBAAqB,EACtB,MAAM,YAAY,CAAC"}
|
package/dist/dropdown/types.d.ts
CHANGED
|
@@ -8,6 +8,12 @@ export type DropdownMultiValue = string[];
|
|
|
8
8
|
export type DropdownSelection = DropdownValue | DropdownMultiValue;
|
|
9
9
|
export type DropdownPlacement = 'auto' | 'up' | 'down';
|
|
10
10
|
export type DropdownMenuAlign = 'left' | 'right';
|
|
11
|
+
/**
|
|
12
|
+
* Vertical alignment of the collapsed trigger's content (label and chevron).
|
|
13
|
+
* Only visible when the trigger is taller than its content, e.g. when the
|
|
14
|
+
* host layout stretches it to fill a table cell.
|
|
15
|
+
*/
|
|
16
|
+
export type DropdownVerticalAlign = 'start' | 'center' | 'end';
|
|
11
17
|
export interface DropdownOption {
|
|
12
18
|
label: string;
|
|
13
19
|
/** Optional text used for keyboard typeahead matching instead of (or in addition to) the label. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,kBAAkB,GAAG,MAAM,EAAE,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEjD,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,mGAAmG;IACnG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,MAAM,MAAM,0BAA0B,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7F,MAAM,MAAM,8BAA8B,GAAG;IAC5C,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D,CAAC,gBAAgB,CAAC,CAAC;AAEpB,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAEtE,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElF,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,OAAO,CAAC;AACtD,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,MAAM,CAAC;AAEzE,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACtC;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/dropdown/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC;AAEnC,MAAM,MAAM,kBAAkB,GAAG,MAAM,EAAE,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG,kBAAkB,CAAC;AAEnE,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,IAAI,GAAG,MAAM,CAAC;AAEvD,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,CAAC;AAEjD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,QAAQ,GAAG,KAAK,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,mGAAmG;IACnG,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,aAAa,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAED,MAAM,MAAM,qBAAqB,GAAG,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnF,MAAM,MAAM,0BAA0B,GAAG,CAAC,KAAK,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAE7F,MAAM,MAAM,8BAA8B,GAAG;IAC5C,cAAc,CAAC,KAAK,EAAE,iBAAiB,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D,CAAC,gBAAgB,CAAC,CAAC;AAEpB,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;AAEtE,MAAM,MAAM,2BAA2B,GAAG,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;AAElF,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG,OAAO,CAAC;AACtD,MAAM,MAAM,uBAAuB,GAAG,CAAC,MAAM,EAAE,cAAc,KAAK,MAAM,CAAC;AAEzE,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,CAAC;AAE1E,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,mBAAmB,EAAE,CAAC;CACtC;AAED,MAAM,MAAM,mBAAmB,GAAG,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,mBAAmB,KACzB,OAAO,CAAC,yBAAyB,CAAC,GAAG,yBAAyB,CAAC"}
|
package/dist/style.css
CHANGED
|
@@ -12,6 +12,14 @@
|
|
|
12
12
|
--suu-color-warning: #d97706;
|
|
13
13
|
--suu-color-info: #2563eb;
|
|
14
14
|
--suu-shadow: 0 12px 30px rgb(15 23 42 / 0.14);
|
|
15
|
+
/* Overlay surfaces (dropdown menus) float above the page: they step the page
|
|
16
|
+
background up toward the surface color instead of reusing it and get a
|
|
17
|
+
deep shadow plus a hairline ring so their outline stays readable even
|
|
18
|
+
where host grid lines (table borders, adjacent inputs) run under them.
|
|
19
|
+
The elevated token references the base palette lazily, so theme and
|
|
20
|
+
consumer-side remaps of surface/border apply automatically. */
|
|
21
|
+
--suu-color-elevated: color-mix(in srgb, var(--suu-color-surface) 45%, var(--suu-color-bg));
|
|
22
|
+
--suu-shadow-overlay: 0 12px 32px rgb(15 23 42 / 0.2), 0 0 0 1px rgb(15 23 42 / 0.06);
|
|
15
23
|
--suu-radius-xs: 4px;
|
|
16
24
|
--suu-radius-sm: 6px;
|
|
17
25
|
--suu-radius-md: 8px;
|
|
@@ -37,6 +45,7 @@
|
|
|
37
45
|
--suu-color-warning: #fbbf24;
|
|
38
46
|
--suu-color-info: #60a5fa;
|
|
39
47
|
--suu-shadow: 0 16px 34px rgb(0 0 0 / 0.32);
|
|
48
|
+
--suu-shadow-overlay: 0 12px 32px rgb(0 0 0 / 0.45), 0 0 0 1px rgb(255 255 255 / 0.025);
|
|
40
49
|
}
|
|
41
50
|
|
|
42
51
|
.suu-visually-hidden {
|
|
@@ -895,6 +904,16 @@
|
|
|
895
904
|
|
|
896
905
|
.suu-dropdown {
|
|
897
906
|
--suu-dropdown-space: 14px;
|
|
907
|
+
/* Menu row semantics, all derived from the theme palette so light and dark
|
|
908
|
+
keep the same ladder: panel frame > group band boundary > option
|
|
909
|
+
separator, and selected > hover. */
|
|
910
|
+
--suu-dropdown-option-separator: color-mix(in srgb, var(--suu-color-border) 24%, transparent);
|
|
911
|
+
--suu-dropdown-group-border: color-mix(in srgb, var(--suu-color-border) 80%, transparent);
|
|
912
|
+
--suu-dropdown-group-bg: color-mix(in srgb, var(--suu-color-muted) 18%, var(--suu-color-elevated));
|
|
913
|
+
--suu-dropdown-group-text: var(--suu-color-text);
|
|
914
|
+
--suu-dropdown-option-hover-bg: color-mix(in srgb, var(--suu-color-muted) 7%, var(--suu-color-elevated));
|
|
915
|
+
--suu-dropdown-option-selected-bg: color-mix(in srgb, var(--suu-color-accent) 12%, var(--suu-color-elevated));
|
|
916
|
+
--suu-dropdown-option-selected-hover-bg: color-mix(in srgb, var(--suu-color-accent) 18%, var(--suu-color-elevated));
|
|
898
917
|
|
|
899
918
|
position: relative;
|
|
900
919
|
display: inline-flex;
|
|
@@ -945,6 +964,31 @@
|
|
|
945
964
|
width: 100%;
|
|
946
965
|
}
|
|
947
966
|
|
|
967
|
+
/* A trigger stretched taller than its content (e.g. filling a tall table
|
|
968
|
+
cell) would float its collapsed label mid-button; the valign modifiers pin
|
|
969
|
+
the label near an edge while keeping a minimal vertical padding so the
|
|
970
|
+
text never touches the button border, and the chevron keeps station
|
|
971
|
+
beside the first or last text line. The doubled class raises specificity
|
|
972
|
+
above host overrides of the base button padding, because the edge gap is
|
|
973
|
+
part of the alignment contract, not a restyle. */
|
|
974
|
+
.suu-dropdown.suu-dropdown--valign-start .suu-dropdown__button {
|
|
975
|
+
align-items: flex-start;
|
|
976
|
+
padding-top: 10px;
|
|
977
|
+
}
|
|
978
|
+
|
|
979
|
+
.suu-dropdown.suu-dropdown--valign-start .suu-dropdown__button .suu-dropdown__chevron {
|
|
980
|
+
margin-top: 0.3em;
|
|
981
|
+
}
|
|
982
|
+
|
|
983
|
+
.suu-dropdown.suu-dropdown--valign-end .suu-dropdown__button {
|
|
984
|
+
align-items: flex-end;
|
|
985
|
+
padding-bottom: 10px;
|
|
986
|
+
}
|
|
987
|
+
|
|
988
|
+
.suu-dropdown.suu-dropdown--valign-end .suu-dropdown__button .suu-dropdown__chevron {
|
|
989
|
+
margin-bottom: 0.3em;
|
|
990
|
+
}
|
|
991
|
+
|
|
948
992
|
.suu-dropdown__button:hover,
|
|
949
993
|
.suu-dropdown__button:focus-visible {
|
|
950
994
|
border-color: var(--suu-color-accent);
|
|
@@ -1018,18 +1062,24 @@
|
|
|
1018
1062
|
transform: translateY(-20%) rotate(45deg);
|
|
1019
1063
|
}
|
|
1020
1064
|
|
|
1065
|
+
/* The menu is a floating overlay, not a table that grew downward: its
|
|
1066
|
+
background steps above the page, the shadow ring keeps the outline readable
|
|
1067
|
+
where host grid lines run under it, and it overhangs the trigger by 4px on
|
|
1068
|
+
each side so its edges never sit on the same lines as the surrounding
|
|
1069
|
+
layout. Internal lines follow the --suu-dropdown-* row tokens so the
|
|
1070
|
+
ladder stays: panel frame > group band boundary > option separator. */
|
|
1021
1071
|
.suu-dropdown__menu {
|
|
1022
1072
|
position: absolute;
|
|
1023
|
-
top: calc(100% +
|
|
1024
|
-
right:
|
|
1073
|
+
top: calc(100% + 4px);
|
|
1074
|
+
right: -4px;
|
|
1025
1075
|
left: auto;
|
|
1026
1076
|
z-index: 100;
|
|
1027
|
-
min-width: 100
|
|
1077
|
+
min-width: calc(100% + 8px);
|
|
1028
1078
|
overflow: hidden;
|
|
1029
1079
|
border: 1px solid var(--suu-color-border);
|
|
1030
1080
|
border-radius: var(--suu-radius);
|
|
1031
|
-
background: var(--suu-color-
|
|
1032
|
-
box-shadow:
|
|
1081
|
+
background: var(--suu-color-elevated);
|
|
1082
|
+
box-shadow: var(--suu-shadow-overlay);
|
|
1033
1083
|
/* Reset inherited host whitespace (e.g. a nowrap table cell) so every menu
|
|
1034
1084
|
text — group titles, status labels — wraps by default; the single-line
|
|
1035
1085
|
fit-content rules set nowrap explicitly where needed. */
|
|
@@ -1057,17 +1107,17 @@
|
|
|
1057
1107
|
|
|
1058
1108
|
.suu-dropdown__menu--left:not(.suu-dropdown__menu--portal) {
|
|
1059
1109
|
right: auto;
|
|
1060
|
-
left:
|
|
1110
|
+
left: -4px;
|
|
1061
1111
|
}
|
|
1062
1112
|
|
|
1063
1113
|
.suu-dropdown__menu--right:not(.suu-dropdown__menu--portal) {
|
|
1064
|
-
right:
|
|
1114
|
+
right: -4px;
|
|
1065
1115
|
left: auto;
|
|
1066
1116
|
}
|
|
1067
1117
|
|
|
1068
1118
|
.suu-dropdown__menu--up:not(.suu-dropdown__menu--portal) {
|
|
1069
1119
|
top: auto;
|
|
1070
|
-
bottom: calc(100% +
|
|
1120
|
+
bottom: calc(100% + 4px);
|
|
1071
1121
|
}
|
|
1072
1122
|
|
|
1073
1123
|
.suu-dropdown__menu--fit-content:not(.suu-dropdown__menu--portal) {
|
|
@@ -1102,26 +1152,31 @@
|
|
|
1102
1152
|
max-height: var(--suu-dropdown-panel-max-height, 100vh);
|
|
1103
1153
|
overflow-y: auto;
|
|
1104
1154
|
overflow-x: hidden;
|
|
1105
|
-
background: var(--suu-color-
|
|
1155
|
+
background: var(--suu-color-elevated);
|
|
1106
1156
|
overscroll-behavior: contain;
|
|
1107
1157
|
}
|
|
1108
1158
|
|
|
1109
1159
|
.suu-dropdown__group + .suu-dropdown__group {
|
|
1110
|
-
border-top: 1px solid var(--suu-
|
|
1160
|
+
border-top: 1px solid var(--suu-dropdown-group-border);
|
|
1111
1161
|
}
|
|
1112
1162
|
|
|
1163
|
+
/* 分组用中性底色和粗体形成标题带,避免与蓝色选中态混淆。
|
|
1164
|
+
font 简写必须位于字号和字重之前,防止覆盖标题层级。 */
|
|
1113
1165
|
.suu-dropdown__group-label {
|
|
1114
1166
|
display: flex;
|
|
1115
1167
|
width: 100%;
|
|
1116
1168
|
border: 0;
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1169
|
+
border-bottom: 1px solid var(--suu-dropdown-group-border);
|
|
1170
|
+
min-height: 32px;
|
|
1171
|
+
padding: 6px 14px;
|
|
1172
|
+
background: var(--suu-dropdown-group-bg);
|
|
1173
|
+
color: var(--suu-dropdown-group-text);
|
|
1120
1174
|
cursor: pointer;
|
|
1121
|
-
font
|
|
1175
|
+
font: inherit;
|
|
1176
|
+
font-size: 0.8125em;
|
|
1122
1177
|
font-weight: 700;
|
|
1178
|
+
line-height: 1.3;
|
|
1123
1179
|
letter-spacing: 0.02em;
|
|
1124
|
-
font: inherit;
|
|
1125
1180
|
text-align: left;
|
|
1126
1181
|
align-items: center;
|
|
1127
1182
|
justify-content: space-between;
|
|
@@ -1150,12 +1205,15 @@
|
|
|
1150
1205
|
transform: rotate(45deg);
|
|
1151
1206
|
}
|
|
1152
1207
|
|
|
1208
|
+
/* 收紧单行选项的留白,长名称仍由内容撑高;分隔线保持弱于分组边界。 */
|
|
1153
1209
|
.suu-dropdown__option {
|
|
1154
|
-
display:
|
|
1210
|
+
display: flex;
|
|
1211
|
+
align-items: center;
|
|
1155
1212
|
width: 100%;
|
|
1156
|
-
|
|
1213
|
+
min-height: 36px;
|
|
1214
|
+
padding: 6px 14px;
|
|
1157
1215
|
border: 0;
|
|
1158
|
-
border-bottom: 1px solid var(--suu-
|
|
1216
|
+
border-bottom: 1px solid var(--suu-dropdown-option-separator);
|
|
1159
1217
|
background: transparent;
|
|
1160
1218
|
color: var(--suu-color-text);
|
|
1161
1219
|
cursor: pointer;
|
|
@@ -1163,14 +1221,13 @@
|
|
|
1163
1221
|
text-align: left;
|
|
1164
1222
|
}
|
|
1165
1223
|
|
|
1166
|
-
|
|
1167
|
-
|
|
1224
|
+
/* 仅有标题的组选项缩进,未分组的「未选择」等操作保持原始对齐。 */
|
|
1225
|
+
.suu-dropdown__group-label ~ .suu-dropdown__option {
|
|
1226
|
+
padding-inline-start: 24px;
|
|
1168
1227
|
}
|
|
1169
1228
|
|
|
1170
1229
|
.suu-dropdown--multiselect .suu-dropdown__option {
|
|
1171
|
-
display: flex;
|
|
1172
1230
|
gap: 10px;
|
|
1173
|
-
align-items: center;
|
|
1174
1231
|
}
|
|
1175
1232
|
|
|
1176
1233
|
.suu-dropdown__checkbox {
|
|
@@ -1207,15 +1264,24 @@
|
|
|
1207
1264
|
.suu-dropdown__option:hover,
|
|
1208
1265
|
.suu-dropdown__option:focus-visible,
|
|
1209
1266
|
.suu-dropdown__option--active {
|
|
1210
|
-
background: var(--suu-
|
|
1267
|
+
background: var(--suu-dropdown-option-hover-bg);
|
|
1211
1268
|
outline: none;
|
|
1212
1269
|
}
|
|
1213
1270
|
|
|
1271
|
+
/* The selected row is a clear area, not just colored text; hover on top of it
|
|
1272
|
+
deepens the tint one step so the two states stay distinguishable. */
|
|
1214
1273
|
.suu-dropdown__option[aria-selected='true'] {
|
|
1274
|
+
background: var(--suu-dropdown-option-selected-bg);
|
|
1215
1275
|
color: var(--suu-color-accent);
|
|
1216
1276
|
font-weight: 700;
|
|
1217
1277
|
}
|
|
1218
1278
|
|
|
1279
|
+
.suu-dropdown__option[aria-selected='true']:hover,
|
|
1280
|
+
.suu-dropdown__option[aria-selected='true']:focus-visible,
|
|
1281
|
+
.suu-dropdown__option[aria-selected='true'].suu-dropdown__option--active {
|
|
1282
|
+
background: var(--suu-dropdown-option-selected-hover-bg);
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1219
1285
|
.suu-dropdown__option--disabled,
|
|
1220
1286
|
.suu-dropdown__option:disabled {
|
|
1221
1287
|
cursor: not-allowed;
|
|
@@ -1228,8 +1294,8 @@
|
|
|
1228
1294
|
gap: 8px;
|
|
1229
1295
|
align-items: center;
|
|
1230
1296
|
padding: 8px 14px;
|
|
1231
|
-
border-bottom: 1px solid var(--suu-
|
|
1232
|
-
background: var(--suu-color-
|
|
1297
|
+
border-bottom: 1px solid var(--suu-dropdown-group-border);
|
|
1298
|
+
background: var(--suu-color-surface);
|
|
1233
1299
|
}
|
|
1234
1300
|
|
|
1235
1301
|
.suu-dropdown__search-icon {
|