@snack-uikit/button-combo 0.0.1-preview-a2f98ef7.0 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +12 -7
  3. package/dist/cjs/ButtonCombo.d.ts +42 -0
  4. package/dist/cjs/{components/ButtonCombo.js → ButtonCombo.js} +39 -27
  5. package/dist/cjs/constants.d.ts +2 -2
  6. package/dist/cjs/constants.js +4 -5
  7. package/dist/cjs/index.d.ts +1 -1
  8. package/dist/cjs/index.js +1 -1
  9. package/dist/cjs/styles.module.css +91 -0
  10. package/dist/cjs/types.d.ts +1 -12
  11. package/dist/cjs/utils.d.ts +2 -0
  12. package/dist/cjs/{components/utils.js → utils.js} +0 -6
  13. package/dist/esm/ButtonCombo.d.ts +42 -0
  14. package/dist/esm/ButtonCombo.js +40 -0
  15. package/dist/esm/constants.d.ts +2 -2
  16. package/dist/esm/constants.js +4 -5
  17. package/dist/esm/index.d.ts +1 -1
  18. package/dist/esm/index.js +1 -1
  19. package/dist/esm/styles.module.css +91 -0
  20. package/dist/esm/types.d.ts +1 -12
  21. package/dist/esm/utils.d.ts +2 -0
  22. package/dist/esm/{components/utils.js → utils.js} +0 -5
  23. package/package.json +4 -4
  24. package/src/ButtonCombo.tsx +127 -0
  25. package/src/constants.ts +6 -6
  26. package/src/index.ts +1 -1
  27. package/src/styles.module.scss +28 -64
  28. package/src/types.ts +5 -19
  29. package/src/utils.ts +13 -0
  30. package/dist/cjs/components/ButtonCombo.d.ts +0 -11
  31. package/dist/cjs/components/index.d.ts +0 -1
  32. package/dist/cjs/components/index.js +0 -25
  33. package/dist/cjs/components/styles.module.css +0 -221
  34. package/dist/cjs/components/utils.d.ts +0 -3
  35. package/dist/esm/components/ButtonCombo.d.ts +0 -11
  36. package/dist/esm/components/ButtonCombo.js +0 -44
  37. package/dist/esm/components/index.d.ts +0 -1
  38. package/dist/esm/components/index.js +0 -1
  39. package/dist/esm/components/styles.module.css +0 -221
  40. package/dist/esm/components/utils.d.ts +0 -3
  41. package/src/components/ButtonCombo.tsx +0 -105
  42. package/src/components/index.ts +0 -1
  43. package/src/components/styles.module.scss +0 -114
  44. package/src/components/utils.ts +0 -25
@@ -0,0 +1,127 @@
1
+ import cn from 'classnames';
2
+ import { forwardRef, useCallback, useMemo } from 'react';
3
+
4
+ import { ButtonFilled, ButtonFilledProps } from '@snack-uikit/button';
5
+ import { ChevronDownSVG, ChevronUpSVG } from '@snack-uikit/icons';
6
+ import { Droplist, DroplistProps, ItemId } from '@snack-uikit/list';
7
+ import { extractSupportProps, useValueControl, WithSupportProps } from '@snack-uikit/utils';
8
+
9
+ import { DROPLIST_SIZE_MAP } from './constants';
10
+ import styles from './styles.module.scss';
11
+ import { Item } from './types';
12
+ import { extractDroplistItemProps } from './utils';
13
+
14
+ export type ButtonComboProps = WithSupportProps<
15
+ Pick<ButtonFilledProps, 'className' | 'disabled' | 'loading' | 'size' | 'tabIndex' | 'fullWidth'> &
16
+ Pick<DroplistProps, 'open' | 'onOpenChange'> & {
17
+ /** CSS-класс Dropdown */
18
+ dropdownClassName?: string;
19
+ /** CSS-класс Option кнопки */
20
+ optionClassName?: string;
21
+ /** CSS-класс Dropdown trigger кнопки */
22
+ dropdownTriggerClassName?: string;
23
+ /** Controlled состояние */
24
+ value?: ItemId;
25
+ /** Controlled обработчик измения состояния */
26
+ onChange?(value: ItemId): void;
27
+ /** Начальное состояние */
28
+ defaultValue?: string;
29
+ /** Начальное состояние лейбла */
30
+ defaultLabel?: string;
31
+ /** Основные элементы списка */
32
+ items: Item[];
33
+ }
34
+ >;
35
+
36
+ export const ButtonCombo = forwardRef<HTMLDivElement, ButtonComboProps>(
37
+ (
38
+ {
39
+ size = 's',
40
+ defaultLabel = '',
41
+ className,
42
+ dropdownClassName,
43
+ optionClassName,
44
+ dropdownTriggerClassName,
45
+ defaultValue,
46
+ items,
47
+ tabIndex,
48
+ fullWidth,
49
+ disabled,
50
+ loading,
51
+ value: valueProp,
52
+ open: openProp,
53
+ onOpenChange,
54
+ onChange,
55
+ ...rest
56
+ },
57
+ ref,
58
+ ) => {
59
+ const [open, setOpen] = useValueControl<boolean>({ value: openProp, onChange: onOpenChange });
60
+ const [value, setValue] = useValueControl<ItemId>({ value: valueProp, defaultValue, onChange });
61
+
62
+ const droplistItems = useMemo(
63
+ () => items.map(extractDroplistItemProps).map(item => ({ ...item, id: item?.id, content: item?.label })),
64
+ [items],
65
+ );
66
+
67
+ const activeOption = useMemo(() => items.find(item => item?.id === value), [items, value]);
68
+
69
+ const handleSelectionChange = useCallback(
70
+ (selectionValue: ItemId) => {
71
+ if (selectionValue) {
72
+ const option = items.find(item => item?.id === selectionValue);
73
+
74
+ option && setValue(selectionValue);
75
+ }
76
+ },
77
+ [items, setValue],
78
+ );
79
+
80
+ return (
81
+ <div
82
+ {...extractSupportProps(rest)}
83
+ ref={ref}
84
+ className={cn(styles.buttonComboWrapper, className)}
85
+ tabIndex={tabIndex}
86
+ data-full-width={fullWidth || undefined}
87
+ >
88
+ <ButtonFilled
89
+ data-type='option'
90
+ size={size}
91
+ label={activeOption?.label ?? defaultLabel}
92
+ onClick={activeOption?.onClick}
93
+ className={optionClassName}
94
+ fullWidth={fullWidth}
95
+ disabled={disabled}
96
+ loading={loading}
97
+ data-test-id='button-combo__option'
98
+ />
99
+ <Droplist
100
+ items={droplistItems}
101
+ open={open}
102
+ onOpenChange={setOpen}
103
+ selection={{
104
+ defaultValue,
105
+ mode: 'single',
106
+ onChange: handleSelectionChange,
107
+ }}
108
+ className={dropdownClassName}
109
+ size={DROPLIST_SIZE_MAP[size]}
110
+ placement='bottom-end'
111
+ closeDroplistOnItemClick
112
+ data-test-id='button-combo__dropdown'
113
+ >
114
+ <ButtonFilled
115
+ data-type='dropdown'
116
+ className={dropdownTriggerClassName}
117
+ size={size}
118
+ disabled={disabled}
119
+ loading={loading}
120
+ icon={open ? <ChevronUpSVG /> : <ChevronDownSVG />}
121
+ data-test-id='button-combo__dropdown-button'
122
+ />
123
+ </Droplist>
124
+ </div>
125
+ );
126
+ },
127
+ );
package/src/constants.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { SIZE, Size } from '@snack-uikit/button-private';
1
+ import { ButtonFilledProps } from '@snack-uikit/button';
2
2
  import { DroplistProps } from '@snack-uikit/list';
3
3
 
4
- export const DROPLIST_SIZE_MAP: Record<Size, DroplistProps['size']> = {
5
- [SIZE.Xs]: 's',
6
- [SIZE.S]: 's',
7
- [SIZE.M]: 'm',
8
- [SIZE.L]: 'l',
4
+ export const DROPLIST_SIZE_MAP: Record<NonNullable<ButtonFilledProps['size']>, DroplistProps['size']> = {
5
+ xs: 's',
6
+ s: 's',
7
+ m: 'm',
8
+ l: 'l',
9
9
  };
package/src/index.ts CHANGED
@@ -1 +1 @@
1
- export * from './components';
1
+ export * from './ButtonCombo';
@@ -1,79 +1,43 @@
1
+ @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-buttonCombo';
1
2
  @use '@snack-uikit/figma-tokens/build/scss/components/styles-tokens-element';
3
+ @use '@snack-uikit/figma-tokens/build/scss/styles-theme-variables';
2
4
 
3
- @mixin icon-fill($color) {
4
- .icon {
5
- color: $color;
6
- }
7
- }
8
-
9
- @mixin label-color($color) {
10
- .label {
11
- color: $color;
12
- }
13
- }
5
+ $sizes: 'xs', 's', 'm', 'l';
14
6
 
15
- @mixin icon-size($icon-sizes, $size) {
16
- .icon {
17
- display: inline-flex;
7
+ .buttonComboWrapper {
8
+ display: inline-flex;
9
+ align-items: center;
18
10
 
19
- svg {
20
- width: styles-tokens-element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
21
- height: styles-tokens-element.$icon-s !important; /* stylelint-disable-line declaration-no-important */
22
- }
11
+ &[data-full-width] {
12
+ flex-grow: 1;
13
+ flex-shrink: 1;
14
+ width: 100%;
23
15
  }
24
- }
25
16
 
26
- @mixin button-anatomy-styles($button-theme, $sizes, $variants, $typography, $hasLabel: true) {
27
- @each $size in $sizes {
28
- &[data-size='#{$size}'] {
29
- @if $hasLabel == true {
30
- .label {
31
- @include styles-tokens-element.composite-var($typography, $size);
32
- }
33
- }
34
-
35
- .icon {
36
- display: inline-flex;
37
- align-items: center;
38
- justify-content: center;
39
-
40
- width: styles-tokens-element.$icon-s;
41
- height: styles-tokens-element.$icon-s;
17
+ button {
18
+ &:not(:focus-visible) {
19
+ position: static;
20
+ }
42
21
 
43
- svg {
44
- max-width: styles-tokens-element.$icon-s;
45
- max-height: styles-tokens-element.$icon-s;
46
- }
47
- }
22
+ &[data-type='option'] {
23
+ @each $size in $sizes {
24
+ &[data-size='#{$size}'] {
25
+ min-width: auto;
48
26
 
49
- @each $variant in $variants {
50
- &[data-variant='#{$variant}'] {
51
- @include styles-tokens-element.composite-var($button-theme, 'container', $size, $variant);
27
+ @include styles-tokens-element.composite-var(styles-tokens-buttonCombo.$button-combo, 'container', $size, 'option');
52
28
  }
53
29
  }
54
- }
55
- }
56
- }
57
30
 
58
- @mixin loading-label-only($button-theme) {
59
- &[data-loading][data-variant='label-only'] {
60
- .icon {
61
- position: absolute;
62
- top: 50%;
63
- left: 50%;
64
- transform: translate(-50%, -50%);
31
+ border-right: styles-theme-variables.$border-width-button-combo-divider solid
32
+ styles-theme-variables.$sys-neutral-decor-default;
65
33
  }
66
34
 
67
- .label {
68
- @include styles-tokens-element.composite-var($button-theme, 'label', 'load-label-only');
35
+ &[data-type='dropdown'] {
36
+ @each $size in $sizes {
37
+ &[data-size='#{$size}'] {
38
+ @include styles-tokens-element.composite-var(styles-tokens-buttonCombo.$button-combo, 'container', $size, 'dropdown');
39
+ }
40
+ }
69
41
  }
70
42
  }
71
- }
72
-
73
- @mixin button-common-state {
74
- &:focus-visible {
75
- @include styles-tokens-element.outline-var(styles-tokens-element.$container-focused-s);
76
-
77
- outline-offset: styles-tokens-element.$spacing-state-focus-offset;
78
- }
79
- }
43
+ }
package/src/types.ts CHANGED
@@ -1,21 +1,7 @@
1
- import { BaseButtonProps } from '@snack-uikit/button-private';
2
1
  import { BaseItemProps } from '@snack-uikit/list';
3
2
 
4
- export type Item = BaseItemProps & {
5
- /** Название */
6
- label?: string;
7
- };
8
-
9
- export type BaseButtonComboProps = Pick<
10
- BaseButtonProps,
11
- 'className' | 'disabled' | 'loading' | 'size' | 'type' | 'tabIndex' | 'fullWidth'
12
- > & {
13
- /** CSS-класс Dropdown */
14
- dropdownClassName?: string;
15
- /** Начальное состояние */
16
- defaultValue?: string;
17
- /** Начальное состояние лейбла */
18
- defaultLabel?: string;
19
- /** Основные элементы списка */
20
- items: Item[];
21
- };
3
+ export type Item = Omit<BaseItemProps, 'onClick' | 'onMouseDown' | 'onKeyDown' | 'onFocus' | 'onBlur'> &
4
+ Required<Pick<BaseItemProps, 'onClick'>> & {
5
+ /** Название */
6
+ label?: string;
7
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,13 @@
1
+ import { Item } from './types';
2
+
3
+ export function extractDroplistItemProps(props: Item): Omit<Item, 'onClick'> {
4
+ return Object.keys(props)
5
+ .filter(item => !item.startsWith('on'))
6
+ .reduce(
7
+ (nextProps, prop) => ({
8
+ ...nextProps,
9
+ [prop]: props[prop as unknown as keyof Item],
10
+ }),
11
+ {},
12
+ );
13
+ }
@@ -1,11 +0,0 @@
1
- import { WithSupportProps } from '@snack-uikit/utils';
2
- import { BaseButtonComboProps, Item } from '../types';
3
- export type ButtonComboProps = WithSupportProps<BaseButtonComboProps>;
4
- export declare const ButtonCombo: import("react").ForwardRefExoticComponent<{
5
- 'data-test-id'?: string;
6
- } & import("react").AriaAttributes & Pick<import("@snack-uikit/button-private").BaseButtonProps, "className" | "tabIndex" | "loading" | "size" | "disabled" | "type" | "fullWidth"> & {
7
- dropdownClassName?: string;
8
- defaultValue?: string;
9
- defaultLabel?: string;
10
- items: Item[];
11
- } & import("react").RefAttributes<HTMLDivElement>>;
@@ -1 +0,0 @@
1
- export * from './ButtonCombo';
@@ -1,25 +0,0 @@
1
- "use strict";
2
-
3
- var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
4
- if (k2 === undefined) k2 = k;
5
- var desc = Object.getOwnPropertyDescriptor(m, k);
6
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
7
- desc = {
8
- enumerable: true,
9
- get: function () {
10
- return m[k];
11
- }
12
- };
13
- }
14
- Object.defineProperty(o, k2, desc);
15
- } : function (o, m, k, k2) {
16
- if (k2 === undefined) k2 = k;
17
- o[k2] = m[k];
18
- });
19
- var __exportStar = void 0 && (void 0).__exportStar || function (m, exports) {
20
- for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
21
- };
22
- Object.defineProperty(exports, "__esModule", {
23
- value: true
24
- });
25
- __exportStar(require("./ButtonCombo"), exports);
@@ -1,221 +0,0 @@
1
- .buttonComboWrapper{
2
- display:inline-flex;
3
- align-items:center;
4
- }
5
- .buttonComboWrapper[data-full-width]{
6
- flex-grow:1;
7
- flex-shrink:1;
8
- width:100%;
9
- }
10
- .buttonComboWrapper button[data-type=option]{
11
- border-right:var(--border-width-button-combo-divider, 1px) solid var(--sys-neutral-decor-default, #dde0ea);
12
- }
13
- .buttonComboWrapper button[data-type=option][data-size=xs]{
14
- height:var(--size-button-xs, 24px);
15
- border-top-left-radius:var(--radius-button-xs, 8px);
16
- border-bottom-left-radius:var(--radius-button-xs, 8px);
17
- padding-right:var(--space-button-xs-from-label, 8px);
18
- padding-left:var(--space-button-xs-from-label, 8px);
19
- border-right-width:var(--border-width-button-combo-divider, 1px);
20
- }
21
- .buttonComboWrapper button[data-type=option][data-size=s]{
22
- height:var(--size-button-s, 32px);
23
- border-top-left-radius:var(--radius-button-s, 12px);
24
- border-bottom-left-radius:var(--radius-button-s, 12px);
25
- padding-right:var(--space-button-s-from-label, 16px);
26
- padding-left:var(--space-button-s-from-label, 16px);
27
- border-right-width:var(--border-width-button-combo-divider, 1px);
28
- }
29
- .buttonComboWrapper button[data-type=option][data-size=m]{
30
- height:var(--size-button-m, 40px);
31
- border-top-left-radius:var(--radius-button-m, 14px);
32
- border-bottom-left-radius:var(--radius-button-m, 14px);
33
- padding-right:var(--space-button-m-from-label, 24px);
34
- padding-left:var(--space-button-m-from-label, 24px);
35
- border-right-width:var(--border-width-button-combo-divider, 1px);
36
- }
37
- .buttonComboWrapper button[data-type=option][data-size=l]{
38
- height:var(--size-button-l, 48px);
39
- border-top-left-radius:var(--radius-button-l, 16px);
40
- border-bottom-left-radius:var(--radius-button-l, 16px);
41
- padding-right:var(--space-button-l-from-label, 32px);
42
- padding-left:var(--space-button-l-from-label, 32px);
43
- border-right-width:var(--border-width-button-combo-divider, 1px);
44
- }
45
- .buttonComboWrapper button[data-type=dropdown][data-size=xs]{
46
- border-top-right-radius:var(--radius-button-xs, 8px);
47
- border-bottom-right-radius:var(--radius-button-xs, 8px);
48
- width:var(--size-button-xs, 24px);
49
- height:var(--size-button-xs, 24px);
50
- }
51
- .buttonComboWrapper button[data-type=dropdown][data-size=s]{
52
- border-top-right-radius:var(--radius-button-s, 12px);
53
- border-bottom-right-radius:var(--radius-button-s, 12px);
54
- width:var(--size-button-s, 32px);
55
- height:var(--size-button-s, 32px);
56
- }
57
- .buttonComboWrapper button[data-type=dropdown][data-size=m]{
58
- border-top-right-radius:var(--radius-button-m, 14px);
59
- border-bottom-right-radius:var(--radius-button-m, 14px);
60
- width:var(--size-button-m, 40px);
61
- height:var(--size-button-m, 40px);
62
- }
63
- .buttonComboWrapper button[data-type=dropdown][data-size=l]{
64
- border-top-right-radius:var(--radius-button-l, 16px);
65
- border-bottom-right-radius:var(--radius-button-l, 16px);
66
- width:var(--size-button-l, 48px);
67
- height:var(--size-button-l, 48px);
68
- }
69
- .buttonComboWrapper button[data-size=xs] .label{
70
- font-family:var(--sans-label-s-font-family, SB Sans Interface);
71
- font-weight:var(--sans-label-s-font-weight, Semibold);
72
- line-height:var(--sans-label-s-line-height, 14px);
73
- font-size:var(--sans-label-s-font-size, 11px);
74
- letter-spacing:var(--sans-label-s-letter-spacing, 0px);
75
- paragraph-spacing:var(--sans-label-s-paragraph-spacing, 6.05px);
76
- }
77
- .buttonComboWrapper button[data-size=xs] .icon{
78
- display:inline-flex;
79
- align-items:center;
80
- justify-content:center;
81
- width:var(--size-icon-container-s, 24px);
82
- height:var(--size-icon-container-s, 24px);
83
- }
84
- .buttonComboWrapper button[data-size=xs] .icon svg{
85
- max-width:var(--size-icon-container-s, 24px);
86
- max-height:var(--size-icon-container-s, 24px);
87
- }
88
- .buttonComboWrapper button[data-size=s] .label{
89
- font-family:var(--sans-label-m-font-family, SB Sans Interface);
90
- font-weight:var(--sans-label-m-font-weight, Semibold);
91
- line-height:var(--sans-label-m-line-height, 16px);
92
- font-size:var(--sans-label-m-font-size, 12px);
93
- letter-spacing:var(--sans-label-m-letter-spacing, 0px);
94
- paragraph-spacing:var(--sans-label-m-paragraph-spacing, 6.6px);
95
- }
96
- .buttonComboWrapper button[data-size=s] .icon{
97
- display:inline-flex;
98
- align-items:center;
99
- justify-content:center;
100
- width:var(--size-icon-container-s, 24px);
101
- height:var(--size-icon-container-s, 24px);
102
- }
103
- .buttonComboWrapper button[data-size=s] .icon svg{
104
- max-width:var(--size-icon-container-s, 24px);
105
- max-height:var(--size-icon-container-s, 24px);
106
- }
107
- .buttonComboWrapper button[data-size=m] .label{
108
- font-family:var(--sans-label-l-font-family, SB Sans Interface);
109
- font-weight:var(--sans-label-l-font-weight, Semibold);
110
- line-height:var(--sans-label-l-line-height, 20px);
111
- font-size:var(--sans-label-l-font-size, 14px);
112
- letter-spacing:var(--sans-label-l-letter-spacing, 0px);
113
- paragraph-spacing:var(--sans-label-l-paragraph-spacing, 7.7px);
114
- }
115
- .buttonComboWrapper button[data-size=m] .icon{
116
- display:inline-flex;
117
- align-items:center;
118
- justify-content:center;
119
- width:var(--size-icon-container-s, 24px);
120
- height:var(--size-icon-container-s, 24px);
121
- }
122
- .buttonComboWrapper button[data-size=m] .icon svg{
123
- max-width:var(--size-icon-container-s, 24px);
124
- max-height:var(--size-icon-container-s, 24px);
125
- }
126
- .buttonComboWrapper button[data-size=l] .label{
127
- font-family:var(--sans-label-l-font-family, SB Sans Interface);
128
- font-weight:var(--sans-label-l-font-weight, Semibold);
129
- line-height:var(--sans-label-l-line-height, 20px);
130
- font-size:var(--sans-label-l-font-size, 14px);
131
- letter-spacing:var(--sans-label-l-letter-spacing, 0px);
132
- paragraph-spacing:var(--sans-label-l-paragraph-spacing, 7.7px);
133
- }
134
- .buttonComboWrapper button[data-size=l] .icon{
135
- display:inline-flex;
136
- align-items:center;
137
- justify-content:center;
138
- width:var(--size-icon-container-s, 24px);
139
- height:var(--size-icon-container-s, 24px);
140
- }
141
- .buttonComboWrapper button[data-size=l] .icon svg{
142
- max-width:var(--size-icon-container-s, 24px);
143
- max-height:var(--size-icon-container-s, 24px);
144
- }
145
- .buttonComboWrapper button[data-loading][data-variant=label-only] .icon{
146
- position:absolute;
147
- top:50%;
148
- left:50%;
149
- transform:translate(-50%, -50%);
150
- }
151
- .buttonComboWrapper button[data-loading][data-variant=label-only] .label{
152
- opacity:var(--opacity-a0, 0);
153
- }
154
- .buttonComboWrapper button[data-appearance=primary]{
155
- background-color:var(--sys-primary-accent-default, #794ed3);
156
- }
157
- .buttonComboWrapper button[data-appearance=primary] .label{
158
- color:var(--sys-primary-on-accent, #fdfbff);
159
- }
160
- .buttonComboWrapper button[data-appearance=primary] .icon{
161
- color:var(--sys-primary-on-accent, #fdfbff);
162
- }
163
- @media (hover: hover){
164
- .buttonComboWrapper button[data-appearance=primary]:hover{
165
- background-color:var(--sys-primary-accent-hovered, #6851a6);
166
- }
167
- .buttonComboWrapper button[data-appearance=primary]:hover .label{
168
- color:var(--sys-primary-on-accent, #fdfbff);
169
- }
170
- .buttonComboWrapper button[data-appearance=primary]:hover .icon{
171
- color:var(--sys-primary-on-accent, #fdfbff);
172
- }
173
- }
174
- @media (hover: none) or (hover: hover){
175
- .buttonComboWrapper button[data-appearance=primary]:focus-visible{
176
- background-color:var(--sys-primary-accent-hovered, #6851a6);
177
- }
178
- .buttonComboWrapper button[data-appearance=primary]:focus-visible .label{
179
- color:var(--sys-primary-on-accent, #fdfbff);
180
- }
181
- .buttonComboWrapper button[data-appearance=primary]:focus-visible .icon{
182
- color:var(--sys-primary-on-accent, #fdfbff);
183
- }
184
- .buttonComboWrapper button[data-appearance=primary]:active{
185
- background-color:var(--sys-primary-accent-pressed, #5b4796);
186
- }
187
- .buttonComboWrapper button[data-appearance=primary]:active .label{
188
- color:var(--sys-primary-on-accent, #fdfbff);
189
- }
190
- .buttonComboWrapper button[data-appearance=primary]:active .icon{
191
- color:var(--sys-primary-on-accent, #fdfbff);
192
- }
193
- .buttonComboWrapper button[data-appearance=primary][data-loading]{
194
- background-color:var(--sys-primary-accent-pressed, #5b4796);
195
- }
196
- .buttonComboWrapper button[data-appearance=primary][data-loading] .label{
197
- color:var(--sys-primary-on-accent, #fdfbff);
198
- }
199
- .buttonComboWrapper button[data-appearance=primary][data-loading] .icon{
200
- color:var(--sys-primary-on-accent, #fdfbff);
201
- }
202
- .buttonComboWrapper button[data-appearance=primary]:disabled, .buttonComboWrapper button[data-appearance=primary][data-disabled]{
203
- background-color:var(--sys-neutral-decor-disabled, #e6e8ef);
204
- }
205
- .buttonComboWrapper button[data-appearance=primary]:disabled .label, .buttonComboWrapper button[data-appearance=primary][data-disabled] .label{
206
- color:var(--sys-neutral-text-light, #8b8e9b);
207
- }
208
- .buttonComboWrapper button[data-appearance=primary]:disabled .icon, .buttonComboWrapper button[data-appearance=primary][data-disabled] .icon{
209
- color:var(--sys-neutral-text-light, #8b8e9b);
210
- }
211
- }
212
- .buttonComboWrapper button[data-appearance=primary]:focus-visible{
213
- z-index:1;
214
- outline-color:var(--sys-available-complementary, #1c1c24);
215
- }
216
- .buttonComboWrapper button:focus-visible{
217
- outline-width:var(--border-state-focus-s-border-width, 2px);
218
- outline-style:var(--border-state-focus-s-border-style, solid);
219
- outline-color:var(--border-state-focus-s-border-color, );
220
- outline-offset:var(--spacing-state-focus-offset, 2px);
221
- }
@@ -1,3 +0,0 @@
1
- import { Item } from '../types';
2
- export declare function extractDroplistItemProps(props: Item): Item;
3
- export declare function extractButtonActionsProps(props: Item): Item;
@@ -1,11 +0,0 @@
1
- import { WithSupportProps } from '@snack-uikit/utils';
2
- import { BaseButtonComboProps, Item } from '../types';
3
- export type ButtonComboProps = WithSupportProps<BaseButtonComboProps>;
4
- export declare const ButtonCombo: import("react").ForwardRefExoticComponent<{
5
- 'data-test-id'?: string;
6
- } & import("react").AriaAttributes & Pick<import("@snack-uikit/button-private").BaseButtonProps, "className" | "tabIndex" | "loading" | "size" | "disabled" | "type" | "fullWidth"> & {
7
- dropdownClassName?: string;
8
- defaultValue?: string;
9
- defaultLabel?: string;
10
- items: Item[];
11
- } & import("react").RefAttributes<HTMLDivElement>>;
@@ -1,44 +0,0 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
13
- import cn from 'classnames';
14
- import { forwardRef, useCallback, useMemo, useState } from 'react';
15
- import { ButtonPrivate, extractCommonButtonProps, HTML_TYPE, SIZE } from '@snack-uikit/button-private';
16
- import { ChevronDownSVG, ChevronUpSVG } from '@snack-uikit/icons';
17
- import { Droplist } from '@snack-uikit/list';
18
- import { extractSupportProps, useLayoutEffect } from '@snack-uikit/utils';
19
- import { DROPLIST_SIZE_MAP } from '../constants';
20
- import styles from './styles.module.css';
21
- import { extractButtonActionsProps, extractDroplistItemProps } from './utils';
22
- export const ButtonCombo = forwardRef((_a, ref) => {
23
- var _b;
24
- var { size = SIZE.S, type = HTML_TYPE.Button, defaultLabel = '', className, dropdownClassName, defaultValue, items, tabIndex, fullWidth } = _a, rest = __rest(_a, ["size", "type", "defaultLabel", "className", "dropdownClassName", "defaultValue", "items", "tabIndex", "fullWidth"]);
25
- const [open, setOpen] = useState(false);
26
- const [activeOption, setActiveOption] = useState({});
27
- const droplistItems = useMemo(() => items.map(extractDroplistItemProps).map(item => (Object.assign(Object.assign({}, item), { id: item === null || item === void 0 ? void 0 : item.id, content: item === null || item === void 0 ? void 0 : item.label }))), [items]);
28
- const handleSelectionChange = useCallback((value) => {
29
- if (value) {
30
- const option = items.find(item => (item === null || item === void 0 ? void 0 : item.id) === value);
31
- option && setActiveOption(option);
32
- }
33
- }, [items]);
34
- useLayoutEffect(() => {
35
- if (defaultValue) {
36
- handleSelectionChange(defaultValue);
37
- }
38
- }, [defaultValue, handleSelectionChange]);
39
- return (_jsxs("div", Object.assign({}, extractSupportProps(rest), { ref: ref, className: cn(styles.buttonComboWrapper, className), tabIndex: tabIndex, "data-full-width": fullWidth || undefined, children: [_jsx(ButtonPrivate, Object.assign({}, extractCommonButtonProps(rest), extractButtonActionsProps(activeOption), { "data-type": 'option', size: size, label: (_b = activeOption === null || activeOption === void 0 ? void 0 : activeOption.label) !== null && _b !== void 0 ? _b : defaultLabel, type: type, fullWidth: fullWidth, iconClassName: styles.icon, labelClassName: styles.label, "data-test-id": 'button-combo__option' })), _jsx(Droplist, { items: droplistItems, open: open, onOpenChange: setOpen, selection: {
40
- defaultValue,
41
- mode: 'single',
42
- onChange: handleSelectionChange,
43
- }, className: dropdownClassName, size: DROPLIST_SIZE_MAP[size], placement: 'bottom-end', closeDroplistOnItemClick: true, "data-test-id": 'button-combo__dropdown', children: _jsx(ButtonPrivate, Object.assign({}, extractCommonButtonProps(rest), { "data-type": 'dropdown', size: size, iconClassName: styles.icon, labelClassName: styles.label, icon: open ? _jsx(ChevronUpSVG, {}) : _jsx(ChevronDownSVG, {}), "data-test-id": 'button-combo__dropdown-button' })) })] })));
44
- });
@@ -1 +0,0 @@
1
- export * from './ButtonCombo';
@@ -1 +0,0 @@
1
- export * from './ButtonCombo';