@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 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 = 6;
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,EAE5B,MAAM,YAAY,CAAC;AAk9BtB,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;SAXw3B,MAAM,GAAG,SAAS;YAAU,iBAAiB;;cAA8C,cAAc,EAAE;mBAAiB,mBAAmB,EAAE,GAAG,SAAS;IACniC,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;;;;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;;;;;kBAUtiC,CAAC;AAC5E,KAAK,QAAQ,GAAG,YAAY,CAAC,OAAO,QAAQ,CAAC,CAAC;AAChD,eAAe,QAAQ,CAAC"}
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,EAC5B,MAAM,YAAY,CAAC;AAiCtB,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;SAVqc,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;;;;YAAwG,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;eAAa,MAAM,GAAG,SAAS;gBAAc,MAAM,GAAG,SAAS;;eAAqC,0BAA0B,GAAG,SAAS;qBAAmB,2BAA2B,GAAG,SAAS;;;kBAUvgC,CAAC;AACvF,KAAK,mBAAmB,GAAG,YAAY,CAAC,OAAO,mBAAmB,CAAC,CAAC;AACtE,eAAe,mBAAmB,CAAC"}
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"}
@@ -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,EACd,MAAM,YAAY,CAAC"}
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"}
@@ -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% + 6px);
1024
- right: 0;
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-bg);
1032
- box-shadow: 0 18px 42px rgb(15 23 42 / 0.16);
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: 0;
1110
+ left: -4px;
1061
1111
  }
1062
1112
 
1063
1113
  .suu-dropdown__menu--right:not(.suu-dropdown__menu--portal) {
1064
- right: 0;
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% + 6px);
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-bg);
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-color-border);
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
- padding: 8px 14px 6px;
1118
- background: var(--suu-color-surface);
1119
- color: var(--suu-color-muted);
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-size: 0.75em;
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: block;
1210
+ display: flex;
1211
+ align-items: center;
1155
1212
  width: 100%;
1156
- padding: 9px 14px;
1213
+ min-height: 36px;
1214
+ padding: 6px 14px;
1157
1215
  border: 0;
1158
- border-bottom: 1px solid var(--suu-color-border);
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
- .suu-dropdown__option--group-first {
1167
- border-top: 1px solid var(--suu-color-border);
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-color-surface);
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-color-border);
1232
- background: var(--suu-color-bg);
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 {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ibobbyts/svelte-ui-utils",
3
- "version": "0.5.2",
3
+ "version": "0.5.4",
4
4
  "description": "Reusable Svelte 5 UI utilities for dialogs, toast notifications, dropdowns, and data tables.",
5
5
  "type": "module",
6
6
  "license": "MIT",