@mindlogic-ai/logician-ui 5.0.0-alpha.15 → 5.0.0-alpha.16
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/dist/components/Select/Combobox.d.ts +1 -1
- package/dist/components/Select/Combobox.d.ts.map +1 -1
- package/dist/components/Select/Combobox.js +9 -2
- package/dist/components/Select/Combobox.js.map +1 -1
- package/dist/components/Select/Combobox.mjs +10 -3
- package/dist/components/Select/Combobox.mjs.map +1 -1
- package/dist/components/Select/Select.d.ts +1 -1
- package/dist/components/Select/Select.d.ts.map +1 -1
- package/dist/components/Select/Select.js +14 -2
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/Select.mjs +15 -3
- package/dist/components/Select/Select.mjs.map +1 -1
- package/dist/components/Select/Select.styles.d.ts +96 -0
- package/dist/components/Select/Select.styles.d.ts.map +1 -1
- package/dist/components/Select/Select.styles.js +75 -0
- package/dist/components/Select/Select.styles.js.map +1 -1
- package/dist/components/Select/Select.styles.mjs +74 -1
- package/dist/components/Select/Select.styles.mjs.map +1 -1
- package/dist/translations/Defaults.translations.json.js +10 -1
- package/dist/translations/Defaults.translations.json.js.map +1 -1
- package/dist/translations/Defaults.translations.json.mjs +10 -2
- package/dist/translations/Defaults.translations.json.mjs.map +1 -1
- package/package.json +1 -1
- package/src/components/Select/Combobox.tsx +28 -3
- package/src/components/Select/Select.clearTrigger.test.tsx +76 -0
- package/src/components/Select/Select.stories.tsx +81 -0
- package/src/components/Select/Select.styles.ts +81 -0
- package/src/components/Select/Select.tsx +28 -2
- package/src/components/Select/Select.usage.mdx +63 -0
- package/src/translations/Defaults.translations.json +7 -0
|
@@ -2,7 +2,7 @@ import { Combobox as ChakraCombobox } from '@chakra-ui/react';
|
|
|
2
2
|
/**
|
|
3
3
|
* Compound Combobox primitives — Chakra's `Combobox` namespace with the
|
|
4
4
|
* Logician design-system styling baked into the visual parts (`Input`,
|
|
5
|
-
* `Content`, `Item`). Use these directly for full compositional control;
|
|
5
|
+
* `Content`, `Item`, `ClearTrigger`). Use these directly for full compositional control;
|
|
6
6
|
* use `ComboboxField` for the common single-select case.
|
|
7
7
|
*/
|
|
8
8
|
export declare const Combobox: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Combobox.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Combobox.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Combobox.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAyE9D;;;;;GAKG;AACH,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;CAmBpB,CAAC"}
|
|
@@ -4,8 +4,10 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var react = require('@chakra-ui/react');
|
|
7
|
+
var useTranslate = require('../../hooks/useTranslate.js');
|
|
7
8
|
var formControls = require('../../theme/formControls.js');
|
|
8
9
|
var mergeCss = require('../../utils/mergeCss.js');
|
|
10
|
+
var index = require('../Icon/index.js');
|
|
9
11
|
var Select_styles = require('./Select.styles.js');
|
|
10
12
|
|
|
11
13
|
const Input = React.forwardRef(function ComboboxInput({ css, ...props }, ref) {
|
|
@@ -23,10 +25,15 @@ const Content = React.forwardRef(function ComboboxContent({ css, ...props }, ref
|
|
|
23
25
|
const Item = React.forwardRef(function ComboboxItem({ css, ...props }, ref) {
|
|
24
26
|
return (jsxRuntime.jsx(react.Combobox.Item, { ref: ref, ...props, css: mergeCss.mergeCss(Select_styles.itemStyles, css) }));
|
|
25
27
|
});
|
|
28
|
+
/** Same × as `Select.ClearTrigger`; see there. */
|
|
29
|
+
const ClearTrigger = React.forwardRef(function ComboboxClearTrigger({ css, children, ...props }, ref) {
|
|
30
|
+
const translate = useTranslate.useTranslate();
|
|
31
|
+
return (jsxRuntime.jsx(react.Combobox.ClearTrigger, { ref: ref, "aria-label": translate('clear_selection'), ...props, css: mergeCss.mergeCss(Select_styles.comboboxClearTriggerStyles, css), children: children ?? jsxRuntime.jsx(index.CloseIcon, { "aria-hidden": true }) }));
|
|
32
|
+
});
|
|
26
33
|
/**
|
|
27
34
|
* Compound Combobox primitives — Chakra's `Combobox` namespace with the
|
|
28
35
|
* Logician design-system styling baked into the visual parts (`Input`,
|
|
29
|
-
* `Content`, `Item`). Use these directly for full compositional control;
|
|
36
|
+
* `Content`, `Item`, `ClearTrigger`). Use these directly for full compositional control;
|
|
30
37
|
* use `ComboboxField` for the common single-select case.
|
|
31
38
|
*/
|
|
32
39
|
const Combobox = {
|
|
@@ -38,7 +45,7 @@ const Combobox = {
|
|
|
38
45
|
Input,
|
|
39
46
|
Trigger: react.Combobox.Trigger,
|
|
40
47
|
IndicatorGroup: react.Combobox.IndicatorGroup,
|
|
41
|
-
ClearTrigger
|
|
48
|
+
ClearTrigger,
|
|
42
49
|
Positioner: react.Combobox.Positioner,
|
|
43
50
|
Content,
|
|
44
51
|
Empty: react.Combobox.Empty,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.js","sources":["../../../src/components/Select/Combobox.tsx"],"sourcesContent":[null],"names":["forwardRef","_jsx","ChakraCombobox","mergeCss","noZoomOnFocus","inputStyles","contentStyles","itemStyles"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Combobox.js","sources":["../../../src/components/Select/Combobox.tsx"],"sourcesContent":[null],"names":["forwardRef","_jsx","ChakraCombobox","mergeCss","noZoomOnFocus","inputStyles","contentStyles","itemStyles","useTranslate","comboboxClearTriggerStyles","CloseIcon"],"mappings":";;;;;;;;;;;;AAeA,MAAM,KAAK,GAAGA,gBAAU,CACtB,SAAS,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;IAC3C,QACEC,cAAA,CAACC,cAAc,CAAC,KAAK,IACnB,GAAG,EAAE,GAAG,EAAA,GACJ,KAAK;;;QAGT,GAAG,EAAEC,iBAAQ,CAACC,0BAAa,EAAEC,yBAAW,EAAE,GAAG,CAAC,EAAA,CAC9C;AAEN,CAAC,CACF;AAED,MAAM,OAAO,GAAGL,gBAAU,CACxB,SAAS,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;IAC7C,QACEC,eAACC,cAAc,CAAC,OAAO,EAAA,EACrB,GAAG,EAAE,GAAG;;;AAGR,QAAA,cAAc,EAAC,mBAAmB,EAAA,GAC9B,KAAK,EACT,GAAG,EAAEC,iBAAQ,CAACG,2BAAa,EAAE,GAAG,CAAC,EAAA,CACjC;AAEN,CAAC,CACF;AAED,MAAM,IAAI,GAAGN,gBAAU,CACrB,SAAS,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;IAC1C,QACEC,eAACC,cAAc,CAAC,IAAI,EAAA,EAClB,GAAG,EAAE,GAAG,EAAA,GACJ,KAAK,EACT,GAAG,EAAEC,iBAAQ,CAACI,wBAAU,EAAE,GAAG,CAAC,EAAA,CAC9B;AAEN,CAAC,CACF;AAED;AACA,MAAM,YAAY,GAAGP,gBAAU,CAG7B,SAAS,oBAAoB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;AAC9D,IAAA,MAAM,SAAS,GAAGQ,yBAAY,EAAE;AAChC,IAAA,QACEP,cAAA,CAACC,cAAc,CAAC,YAAY,EAAA,EAC1B,GAAG,EAAE,GAAG,EAAA,YAAA,EACI,SAAS,CAAC,iBAAiB,CAAW,EAAA,GAC9C,KAAK,EACT,GAAG,EAAEC,iBAAQ,CAACM,wCAA0B,EAAE,GAAG,CAAC,EAAA,QAAA,EAE7C,QAAQ,IAAIR,cAAA,CAACS,eAAS,EAAA,EAAA,aAAA,EAAA,IAAA,EAAA,CAAe,EAAA,CACV;AAElC,CAAC,CAAC;AAEF;;;;;AAKG;AACI,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAER,cAAc,CAAC,IAAI;IACzB,aAAa,EAAEA,cAAc,CAAC,aAAa;IAC3C,OAAO,EAAEA,cAAc,CAAC,OAAO;IAC/B,KAAK,EAAEA,cAAc,CAAC,KAAK;IAC3B,OAAO,EAAEA,cAAc,CAAC,OAAO;IAC/B,KAAK;IACL,OAAO,EAAEA,cAAc,CAAC,OAAO;IAC/B,cAAc,EAAEA,cAAc,CAAC,cAAc;IAC7C,YAAY;IACZ,UAAU,EAAEA,cAAc,CAAC,UAAU;IACrC,OAAO;IACP,KAAK,EAAEA,cAAc,CAAC,KAAK;IAC3B,SAAS,EAAEA,cAAc,CAAC,SAAS;IACnC,cAAc,EAAEA,cAAc,CAAC,cAAc;IAC7C,IAAI;IACJ,QAAQ,EAAEA,cAAc,CAAC,QAAQ;IACjC,aAAa,EAAEA,cAAc,CAAC,aAAa;IAC3C,WAAW,EAAEA,cAAc,CAAC,WAAW;;;;;"}
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { forwardRef } from 'react';
|
|
4
4
|
import { Combobox as Combobox$1 } from '@chakra-ui/react';
|
|
5
|
+
import { useTranslate } from '../../hooks/useTranslate.mjs';
|
|
5
6
|
import { noZoomOnFocus } from '../../theme/formControls.mjs';
|
|
6
7
|
import { mergeCss } from '../../utils/mergeCss.mjs';
|
|
7
|
-
import {
|
|
8
|
+
import { CloseIcon } from '../Icon/index.mjs';
|
|
9
|
+
import { inputStyles, contentStyles, itemStyles, comboboxClearTriggerStyles } from './Select.styles.mjs';
|
|
8
10
|
|
|
9
11
|
const Input = forwardRef(function ComboboxInput({ css, ...props }, ref) {
|
|
10
12
|
return (jsx(Combobox$1.Input, { ref: ref, ...props,
|
|
@@ -21,10 +23,15 @@ const Content = forwardRef(function ComboboxContent({ css, ...props }, ref) {
|
|
|
21
23
|
const Item = forwardRef(function ComboboxItem({ css, ...props }, ref) {
|
|
22
24
|
return (jsx(Combobox$1.Item, { ref: ref, ...props, css: mergeCss(itemStyles, css) }));
|
|
23
25
|
});
|
|
26
|
+
/** Same × as `Select.ClearTrigger`; see there. */
|
|
27
|
+
const ClearTrigger = forwardRef(function ComboboxClearTrigger({ css, children, ...props }, ref) {
|
|
28
|
+
const translate = useTranslate();
|
|
29
|
+
return (jsx(Combobox$1.ClearTrigger, { ref: ref, "aria-label": translate('clear_selection'), ...props, css: mergeCss(comboboxClearTriggerStyles, css), children: children ?? jsx(CloseIcon, { "aria-hidden": true }) }));
|
|
30
|
+
});
|
|
24
31
|
/**
|
|
25
32
|
* Compound Combobox primitives — Chakra's `Combobox` namespace with the
|
|
26
33
|
* Logician design-system styling baked into the visual parts (`Input`,
|
|
27
|
-
* `Content`, `Item`). Use these directly for full compositional control;
|
|
34
|
+
* `Content`, `Item`, `ClearTrigger`). Use these directly for full compositional control;
|
|
28
35
|
* use `ComboboxField` for the common single-select case.
|
|
29
36
|
*/
|
|
30
37
|
const Combobox = {
|
|
@@ -36,7 +43,7 @@ const Combobox = {
|
|
|
36
43
|
Input,
|
|
37
44
|
Trigger: Combobox$1.Trigger,
|
|
38
45
|
IndicatorGroup: Combobox$1.IndicatorGroup,
|
|
39
|
-
ClearTrigger
|
|
46
|
+
ClearTrigger,
|
|
40
47
|
Positioner: Combobox$1.Positioner,
|
|
41
48
|
Content,
|
|
42
49
|
Empty: Combobox$1.Empty,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Combobox.mjs","sources":["../../../src/components/Select/Combobox.tsx"],"sourcesContent":[null],"names":["_jsx","ChakraCombobox"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Combobox.mjs","sources":["../../../src/components/Select/Combobox.tsx"],"sourcesContent":[null],"names":["_jsx","ChakraCombobox"],"mappings":";;;;;;;;;;AAeA,MAAM,KAAK,GAAG,UAAU,CACtB,SAAS,aAAa,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;IAC3C,QACEA,GAAA,CAACC,UAAc,CAAC,KAAK,IACnB,GAAG,EAAE,GAAG,EAAA,GACJ,KAAK;;;QAGT,GAAG,EAAE,QAAQ,CAAC,aAAa,EAAE,WAAW,EAAE,GAAG,CAAC,EAAA,CAC9C;AAEN,CAAC,CACF;AAED,MAAM,OAAO,GAAG,UAAU,CACxB,SAAS,eAAe,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;IAC7C,QACED,IAACC,UAAc,CAAC,OAAO,EAAA,EACrB,GAAG,EAAE,GAAG;;;AAGR,QAAA,cAAc,EAAC,mBAAmB,EAAA,GAC9B,KAAK,EACT,GAAG,EAAE,QAAQ,CAAC,aAAa,EAAE,GAAG,CAAC,EAAA,CACjC;AAEN,CAAC,CACF;AAED,MAAM,IAAI,GAAG,UAAU,CACrB,SAAS,YAAY,CAAC,EAAE,GAAG,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;IAC1C,QACED,IAACC,UAAc,CAAC,IAAI,EAAA,EAClB,GAAG,EAAE,GAAG,EAAA,GACJ,KAAK,EACT,GAAG,EAAE,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,EAAA,CAC9B;AAEN,CAAC,CACF;AAED;AACA,MAAM,YAAY,GAAG,UAAU,CAG7B,SAAS,oBAAoB,CAAC,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,EAAE,GAAG,EAAA;AAC9D,IAAA,MAAM,SAAS,GAAG,YAAY,EAAE;AAChC,IAAA,QACED,GAAA,CAACC,UAAc,CAAC,YAAY,EAAA,EAC1B,GAAG,EAAE,GAAG,EAAA,YAAA,EACI,SAAS,CAAC,iBAAiB,CAAW,EAAA,GAC9C,KAAK,EACT,GAAG,EAAE,QAAQ,CAAC,0BAA0B,EAAE,GAAG,CAAC,EAAA,QAAA,EAE7C,QAAQ,IAAID,GAAA,CAAC,SAAS,EAAA,EAAA,aAAA,EAAA,IAAA,EAAA,CAAe,EAAA,CACV;AAElC,CAAC,CAAC;AAEF;;;;;AAKG;AACI,MAAM,QAAQ,GAAG;IACtB,IAAI,EAAEC,UAAc,CAAC,IAAI;IACzB,aAAa,EAAEA,UAAc,CAAC,aAAa;IAC3C,OAAO,EAAEA,UAAc,CAAC,OAAO;IAC/B,KAAK,EAAEA,UAAc,CAAC,KAAK;IAC3B,OAAO,EAAEA,UAAc,CAAC,OAAO;IAC/B,KAAK;IACL,OAAO,EAAEA,UAAc,CAAC,OAAO;IAC/B,cAAc,EAAEA,UAAc,CAAC,cAAc;IAC7C,YAAY;IACZ,UAAU,EAAEA,UAAc,CAAC,UAAU;IACrC,OAAO;IACP,KAAK,EAAEA,UAAc,CAAC,KAAK;IAC3B,SAAS,EAAEA,UAAc,CAAC,SAAS;IACnC,cAAc,EAAEA,UAAc,CAAC,cAAc;IAC7C,IAAI;IACJ,QAAQ,EAAEA,UAAc,CAAC,QAAQ;IACjC,aAAa,EAAEA,UAAc,CAAC,aAAa;IAC3C,WAAW,EAAEA,UAAc,CAAC,WAAW;;;;;"}
|
|
@@ -6,7 +6,7 @@ export interface SelectTriggerProps extends ChakraSelect.TriggerProps {
|
|
|
6
6
|
/**
|
|
7
7
|
* Compound Select primitives — Chakra's `Select` namespace with the Logician
|
|
8
8
|
* design-system styling baked into the visual parts (`Trigger`, `Content`,
|
|
9
|
-
* `Item`, `Indicator`). Use these directly for full compositional control
|
|
9
|
+
* `Item`, `Indicator`, `ClearTrigger`). Use these directly for full compositional control
|
|
10
10
|
* (multi-select, grouped options, custom layouts); use `SelectField` for the
|
|
11
11
|
* common single-select case.
|
|
12
12
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"Select.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,YAAY,EAAE,MAAM,kBAAkB,CAAC;AAc1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,MAAM,WAAW,kBAAmB,SAAQ,YAAY,CAAC,YAAY;IACnE,OAAO,CAAC,EAAE,aAAa,CAAC;CACzB;AA4ED;;;;;;GAMG;AACH,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;CAoBlB,CAAC"}
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
var React = require('react');
|
|
6
6
|
var react = require('@chakra-ui/react');
|
|
7
|
+
var useTranslate = require('../../hooks/useTranslate.js');
|
|
7
8
|
var mergeCss = require('../../utils/mergeCss.js');
|
|
9
|
+
var index = require('../Icon/index.js');
|
|
8
10
|
var Select_styles = require('./Select.styles.js');
|
|
9
11
|
|
|
10
12
|
const Trigger = React.forwardRef(function SelectTrigger({ css, variant = 'outline', ...props }, ref) {
|
|
@@ -22,10 +24,20 @@ const Item = React.forwardRef(function SelectItem({ css, ...props }, ref) {
|
|
|
22
24
|
const Indicator = React.forwardRef(function SelectIndicator({ css, ...props }, ref) {
|
|
23
25
|
return (jsxRuntime.jsx(react.Select.Indicator, { ref: ref, ...props, css: mergeCss.mergeCss(Select_styles.indicatorStyles, css) }));
|
|
24
26
|
});
|
|
27
|
+
/**
|
|
28
|
+
* The × that empties the selection. Draws `CloseIcon` when no children are
|
|
29
|
+
* passed, and names itself in the provider's language: Chakra's own name is
|
|
30
|
+
* the English "Clear value" in every locale. Pass `aria-label` to say what is
|
|
31
|
+
* being cleared ("조직 선택 지우기").
|
|
32
|
+
*/
|
|
33
|
+
const ClearTrigger = React.forwardRef(function SelectClearTrigger({ css, children, ...props }, ref) {
|
|
34
|
+
const translate = useTranslate.useTranslate();
|
|
35
|
+
return (jsxRuntime.jsx(react.Select.ClearTrigger, { ref: ref, "aria-label": translate('clear_selection'), ...props, css: mergeCss.mergeCss(Select_styles.selectClearTriggerStyles, css), children: children ?? jsxRuntime.jsx(index.CloseIcon, { "aria-hidden": true }) }));
|
|
36
|
+
});
|
|
25
37
|
/**
|
|
26
38
|
* Compound Select primitives — Chakra's `Select` namespace with the Logician
|
|
27
39
|
* design-system styling baked into the visual parts (`Trigger`, `Content`,
|
|
28
|
-
* `Item`, `Indicator`). Use these directly for full compositional control
|
|
40
|
+
* `Item`, `Indicator`, `ClearTrigger`). Use these directly for full compositional control
|
|
29
41
|
* (multi-select, grouped options, custom layouts); use `SelectField` for the
|
|
30
42
|
* common single-select case.
|
|
31
43
|
*/
|
|
@@ -39,7 +51,7 @@ const Select = {
|
|
|
39
51
|
ValueText: react.Select.ValueText,
|
|
40
52
|
IndicatorGroup: react.Select.IndicatorGroup,
|
|
41
53
|
Indicator,
|
|
42
|
-
ClearTrigger
|
|
54
|
+
ClearTrigger,
|
|
43
55
|
HiddenSelect: react.Select.HiddenSelect,
|
|
44
56
|
Positioner: react.Select.Positioner,
|
|
45
57
|
Content,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.js","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":[null],"names":["forwardRef","_jsx","ChakraSelect","mergeCss","triggerStyles","ghostTriggerStyles","contentStyles","itemStyles","indicatorStyles"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Select.js","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":[null],"names":["forwardRef","_jsx","ChakraSelect","mergeCss","triggerStyles","ghostTriggerStyles","contentStyles","itemStyles","indicatorStyles","useTranslate","selectClearTriggerStyles","CloseIcon"],"mappings":"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"}
|
|
@@ -2,8 +2,10 @@
|
|
|
2
2
|
import { jsx } from 'react/jsx-runtime';
|
|
3
3
|
import { forwardRef } from 'react';
|
|
4
4
|
import { Select as Select$1 } from '@chakra-ui/react';
|
|
5
|
+
import { useTranslate } from '../../hooks/useTranslate.mjs';
|
|
5
6
|
import { mergeCss } from '../../utils/mergeCss.mjs';
|
|
6
|
-
import {
|
|
7
|
+
import { CloseIcon } from '../Icon/index.mjs';
|
|
8
|
+
import { ghostTriggerStyles, triggerStyles, contentStyles, itemStyles, indicatorStyles, selectClearTriggerStyles } from './Select.styles.mjs';
|
|
7
9
|
|
|
8
10
|
const Trigger = forwardRef(function SelectTrigger({ css, variant = 'outline', ...props }, ref) {
|
|
9
11
|
return (jsx(Select$1.Trigger, { ref: ref, ...props, css: mergeCss(triggerStyles, variant === 'ghost' && ghostTriggerStyles, css) }));
|
|
@@ -20,10 +22,20 @@ const Item = forwardRef(function SelectItem({ css, ...props }, ref) {
|
|
|
20
22
|
const Indicator = forwardRef(function SelectIndicator({ css, ...props }, ref) {
|
|
21
23
|
return (jsx(Select$1.Indicator, { ref: ref, ...props, css: mergeCss(indicatorStyles, css) }));
|
|
22
24
|
});
|
|
25
|
+
/**
|
|
26
|
+
* The × that empties the selection. Draws `CloseIcon` when no children are
|
|
27
|
+
* passed, and names itself in the provider's language: Chakra's own name is
|
|
28
|
+
* the English "Clear value" in every locale. Pass `aria-label` to say what is
|
|
29
|
+
* being cleared ("조직 선택 지우기").
|
|
30
|
+
*/
|
|
31
|
+
const ClearTrigger = forwardRef(function SelectClearTrigger({ css, children, ...props }, ref) {
|
|
32
|
+
const translate = useTranslate();
|
|
33
|
+
return (jsx(Select$1.ClearTrigger, { ref: ref, "aria-label": translate('clear_selection'), ...props, css: mergeCss(selectClearTriggerStyles, css), children: children ?? jsx(CloseIcon, { "aria-hidden": true }) }));
|
|
34
|
+
});
|
|
23
35
|
/**
|
|
24
36
|
* Compound Select primitives — Chakra's `Select` namespace with the Logician
|
|
25
37
|
* design-system styling baked into the visual parts (`Trigger`, `Content`,
|
|
26
|
-
* `Item`, `Indicator`). Use these directly for full compositional control
|
|
38
|
+
* `Item`, `Indicator`, `ClearTrigger`). Use these directly for full compositional control
|
|
27
39
|
* (multi-select, grouped options, custom layouts); use `SelectField` for the
|
|
28
40
|
* common single-select case.
|
|
29
41
|
*/
|
|
@@ -37,7 +49,7 @@ const Select = {
|
|
|
37
49
|
ValueText: Select$1.ValueText,
|
|
38
50
|
IndicatorGroup: Select$1.IndicatorGroup,
|
|
39
51
|
Indicator,
|
|
40
|
-
ClearTrigger
|
|
52
|
+
ClearTrigger,
|
|
41
53
|
HiddenSelect: Select$1.HiddenSelect,
|
|
42
54
|
Positioner: Select$1.Positioner,
|
|
43
55
|
Content,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.mjs","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":[null],"names":["_jsx","ChakraSelect"],"mappings":"
|
|
1
|
+
{"version":3,"file":"Select.mjs","sources":["../../../src/components/Select/Select.tsx"],"sourcesContent":[null],"names":["_jsx","ChakraSelect"],"mappings":"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"}
|
|
@@ -14,6 +14,12 @@ export declare const triggerStyles: {
|
|
|
14
14
|
borderColor: string;
|
|
15
15
|
boxShadow: string;
|
|
16
16
|
};
|
|
17
|
+
'[data-part=control]:has([data-part=clear-trigger]:not([hidden])) > &': {
|
|
18
|
+
pe: string;
|
|
19
|
+
'& [data-part=value-text]': {
|
|
20
|
+
maxW: string;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
17
23
|
bg: string;
|
|
18
24
|
color: string;
|
|
19
25
|
borderColor: string;
|
|
@@ -76,6 +82,12 @@ export declare const ghostTriggerStyles: {
|
|
|
76
82
|
};
|
|
77
83
|
/** Combobox text input — the typeable control. */
|
|
78
84
|
export declare const inputStyles: {
|
|
85
|
+
'[data-part=control]:has([data-part=clear-trigger]:not([hidden])) > &': {
|
|
86
|
+
pe: string;
|
|
87
|
+
'& [data-part=value-text]': {
|
|
88
|
+
maxW: string;
|
|
89
|
+
};
|
|
90
|
+
};
|
|
79
91
|
bg: string;
|
|
80
92
|
color: string;
|
|
81
93
|
borderColor: string;
|
|
@@ -147,4 +159,88 @@ export declare const itemStyles: {
|
|
|
147
159
|
export declare const indicatorStyles: {
|
|
148
160
|
color: string;
|
|
149
161
|
};
|
|
162
|
+
export declare const selectClearTriggerStyles: {
|
|
163
|
+
position: string;
|
|
164
|
+
display: string;
|
|
165
|
+
alignItems: string;
|
|
166
|
+
justifyContent: string;
|
|
167
|
+
boxSize: string;
|
|
168
|
+
me: string;
|
|
169
|
+
color: string;
|
|
170
|
+
cursor: string;
|
|
171
|
+
_hover: {
|
|
172
|
+
color: string;
|
|
173
|
+
};
|
|
174
|
+
_after: {
|
|
175
|
+
content: string;
|
|
176
|
+
position: string;
|
|
177
|
+
insetEnd: string;
|
|
178
|
+
top: string;
|
|
179
|
+
transform: string;
|
|
180
|
+
h: string;
|
|
181
|
+
borderEndWidth: string;
|
|
182
|
+
borderColor: string;
|
|
183
|
+
pointerEvents: string;
|
|
184
|
+
};
|
|
185
|
+
_hidden: {
|
|
186
|
+
display: string;
|
|
187
|
+
};
|
|
188
|
+
'& svg': {
|
|
189
|
+
width: string;
|
|
190
|
+
height: string;
|
|
191
|
+
};
|
|
192
|
+
'@media (pointer: coarse)': {
|
|
193
|
+
'&::before': {
|
|
194
|
+
content: string;
|
|
195
|
+
position: string;
|
|
196
|
+
insetEnd: number;
|
|
197
|
+
top: string;
|
|
198
|
+
transform: string;
|
|
199
|
+
width: string;
|
|
200
|
+
height: string;
|
|
201
|
+
};
|
|
202
|
+
};
|
|
203
|
+
};
|
|
204
|
+
export declare const comboboxClearTriggerStyles: {
|
|
205
|
+
position: string;
|
|
206
|
+
display: string;
|
|
207
|
+
alignItems: string;
|
|
208
|
+
justifyContent: string;
|
|
209
|
+
boxSize: string;
|
|
210
|
+
me: string;
|
|
211
|
+
color: string;
|
|
212
|
+
cursor: string;
|
|
213
|
+
_hover: {
|
|
214
|
+
color: string;
|
|
215
|
+
};
|
|
216
|
+
_after: {
|
|
217
|
+
content: string;
|
|
218
|
+
position: string;
|
|
219
|
+
insetEnd: string;
|
|
220
|
+
top: string;
|
|
221
|
+
transform: string;
|
|
222
|
+
h: string;
|
|
223
|
+
borderEndWidth: string;
|
|
224
|
+
borderColor: string;
|
|
225
|
+
pointerEvents: string;
|
|
226
|
+
};
|
|
227
|
+
_hidden: {
|
|
228
|
+
display: string;
|
|
229
|
+
};
|
|
230
|
+
'& svg': {
|
|
231
|
+
width: string;
|
|
232
|
+
height: string;
|
|
233
|
+
};
|
|
234
|
+
'@media (pointer: coarse)': {
|
|
235
|
+
'&::before': {
|
|
236
|
+
content: string;
|
|
237
|
+
position: string;
|
|
238
|
+
insetEnd: number;
|
|
239
|
+
top: string;
|
|
240
|
+
transform: string;
|
|
241
|
+
width: string;
|
|
242
|
+
height: string;
|
|
243
|
+
};
|
|
244
|
+
};
|
|
245
|
+
};
|
|
150
246
|
//# sourceMappingURL=Select.styles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"Select.styles.d.ts","sourceRoot":"","sources":["../../../src/components/Select/Select.styles.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAgDH,8CAA8C;AAC9C,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAQzB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;CAoB9B,CAAC;AAEF,kDAAkD;AAClD,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAGvB,CAAC;AAEF,mDAAmD;AACnD,eAAO,MAAM,aAAa;;;;;;;CAOzB,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;CAG9B,CAAC;AAEF,sDAAsD;AACtD,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;CAWtB,CAAC;AAEF,yEAAyE;AACzE,eAAO,MAAM,eAAe;;CAE3B,CAAC;AAwDF,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAEpC,CAAC;AAEF,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAEtC,CAAC"}
|
|
@@ -37,9 +37,26 @@ const fieldBase = {
|
|
|
37
37
|
fontWeight: 'semibold',
|
|
38
38
|
},
|
|
39
39
|
};
|
|
40
|
+
/**
|
|
41
|
+
* Room for the × and its divider at the end of the value, while the × shows.
|
|
42
|
+
*
|
|
43
|
+
* The indicator group overlays the value. Chakra keeps the value off the
|
|
44
|
+
* chevron with `maxW: 80%` on a Select (too little in a narrow filter) and a
|
|
45
|
+
* 1.5× height padding on a Combobox, and neither counts the × with its
|
|
46
|
+
* divider. This reserves the whole group instead: padding on both sides, the
|
|
47
|
+
* × (`8`) with its `me` (`1`), the group `gap` (`1`) and the chevron (`1em`),
|
|
48
|
+
* so a long value ends in an ellipsis before the ×.
|
|
49
|
+
*/
|
|
50
|
+
const clearTriggerRoom = (paddingVar) => ({
|
|
51
|
+
'[data-part=control]:has([data-part=clear-trigger]:not([hidden])) > &': {
|
|
52
|
+
pe: `calc(var(${paddingVar}) * 2 + 3.5em)`,
|
|
53
|
+
'& [data-part=value-text]': { maxW: 'none' },
|
|
54
|
+
},
|
|
55
|
+
});
|
|
40
56
|
/** Select trigger — the clickable control. */
|
|
41
57
|
const triggerStyles = {
|
|
42
58
|
...fieldBase,
|
|
59
|
+
...clearTriggerRoom('--select-trigger-padding-x'),
|
|
43
60
|
cursor: 'pointer',
|
|
44
61
|
_open: {
|
|
45
62
|
borderColor: 'primary.main',
|
|
@@ -78,6 +95,7 @@ const ghostTriggerStyles = {
|
|
|
78
95
|
/** Combobox text input — the typeable control. */
|
|
79
96
|
const inputStyles = {
|
|
80
97
|
...fieldBase,
|
|
98
|
+
...clearTriggerRoom('--combobox-input-padding-x'),
|
|
81
99
|
};
|
|
82
100
|
/** Dropdown panel for both Select and Combobox. */
|
|
83
101
|
const contentStyles = {
|
|
@@ -114,12 +132,69 @@ const itemStyles = {
|
|
|
114
132
|
const indicatorStyles = {
|
|
115
133
|
color: 'fg.muted',
|
|
116
134
|
};
|
|
135
|
+
/**
|
|
136
|
+
* Clear (×) button for both Select and Combobox.
|
|
137
|
+
*
|
|
138
|
+
* Chakra's recipe gives this part a colour and no size, and its default icon
|
|
139
|
+
* is `1em`, so a bare `ClearTrigger` drew a 21px × next to a 14px chevron. The
|
|
140
|
+
* × is the secondary action, so it is smaller (`3.5`, 12px at 14px text) and
|
|
141
|
+
* lighter (`fg.icon`) than the chevron, on an `8` box. `& svg` rather than
|
|
142
|
+
* `_icon` so the size also wins over an icon passed with its own `boxSize`.
|
|
143
|
+
*
|
|
144
|
+
* On a touch screen the hit area widens to 44px, toward the value only: the
|
|
145
|
+
* chevron sits to the right and has to keep opening the list. The height stays
|
|
146
|
+
* the control's own height (`heightVar`), so the area never reaches the field
|
|
147
|
+
* above or below. Every control height is over the 24px KWCAG minimum.
|
|
148
|
+
*/
|
|
149
|
+
const clearTriggerStyles = (heightVar) => ({
|
|
150
|
+
position: 'relative',
|
|
151
|
+
display: 'inline-flex',
|
|
152
|
+
alignItems: 'center',
|
|
153
|
+
justifyContent: 'center',
|
|
154
|
+
boxSize: '8',
|
|
155
|
+
me: '1',
|
|
156
|
+
color: 'fg.icon',
|
|
157
|
+
cursor: 'pointer',
|
|
158
|
+
_hover: { color: 'fg.default' },
|
|
159
|
+
// The divider marks where opening starts: it sits in the `me` gap, takes no
|
|
160
|
+
// clicks, and everything right of it belongs to the chevron.
|
|
161
|
+
_after: {
|
|
162
|
+
content: '""',
|
|
163
|
+
position: 'absolute',
|
|
164
|
+
insetEnd: '-1',
|
|
165
|
+
top: '50%',
|
|
166
|
+
transform: 'translateY(-50%)',
|
|
167
|
+
h: '4',
|
|
168
|
+
borderEndWidth: '1px',
|
|
169
|
+
borderColor: 'border.subtle',
|
|
170
|
+
pointerEvents: 'none',
|
|
171
|
+
},
|
|
172
|
+
// zag hides the × with the `hidden` attribute while nothing is selected,
|
|
173
|
+
// and the `display` above would otherwise override it.
|
|
174
|
+
_hidden: { display: 'none' },
|
|
175
|
+
'& svg': { width: '3.5', height: '3.5' },
|
|
176
|
+
'@media (pointer: coarse)': {
|
|
177
|
+
'&::before': {
|
|
178
|
+
content: '""',
|
|
179
|
+
position: 'absolute',
|
|
180
|
+
insetEnd: 0,
|
|
181
|
+
top: '50%',
|
|
182
|
+
transform: 'translateY(-50%)',
|
|
183
|
+
width: '44px',
|
|
184
|
+
height: `var(${heightVar})`,
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
});
|
|
188
|
+
const selectClearTriggerStyles = clearTriggerStyles('--select-trigger-height');
|
|
189
|
+
const comboboxClearTriggerStyles = clearTriggerStyles('--combobox-input-height');
|
|
117
190
|
|
|
191
|
+
exports.comboboxClearTriggerStyles = comboboxClearTriggerStyles;
|
|
118
192
|
exports.contentStyles = contentStyles;
|
|
119
193
|
exports.ghostContentStyles = ghostContentStyles;
|
|
120
194
|
exports.ghostTriggerStyles = ghostTriggerStyles;
|
|
121
195
|
exports.indicatorStyles = indicatorStyles;
|
|
122
196
|
exports.inputStyles = inputStyles;
|
|
123
197
|
exports.itemStyles = itemStyles;
|
|
198
|
+
exports.selectClearTriggerStyles = selectClearTriggerStyles;
|
|
124
199
|
exports.triggerStyles = triggerStyles;
|
|
125
200
|
//# sourceMappingURL=Select.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.styles.js","sources":["../../../src/components/Select/Select.styles.ts"],"sourcesContent":[null],"names":["disabledControl","disabledText"],"mappings":";;;;;AAAA;;;;;;;;AAQG;AAIH,MAAM,SAAS,GAAG;AAChB,IAAA,eAAe,EAAE,mCAAmC;AACpD,IAAA,eAAe,EAAE,mCAAmC;CACrD;AAED,MAAM,SAAS,GAAG;AAChB,IAAA,GAAG,SAAS;AACZ,IAAA,EAAE,EAAE,YAAY;AAChB,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,WAAW,EAAE,gBAAgB;AAC7B,IAAA,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;AAClC,IAAA,MAAM,EAAE;AACN,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,SAAS,EAAE,6CAA6C;AACzD,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,MAAM,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE;AACvC,QAAA,MAAM,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE;AACxC,KAAA;AACD,IAAA,SAAS,EAAE;AACT,QAAA,GAAGA,+BAAe;AAClB,QAAA,MAAM,EAAE,aAAa;AACrB,QAAA,UAAU,EAAE,UAAU;AACvB,KAAA;CACF;AAED;AACO,MAAM,aAAa,GAAG;AAC3B,IAAA,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"Select.styles.js","sources":["../../../src/components/Select/Select.styles.ts"],"sourcesContent":[null],"names":["disabledControl","disabledText"],"mappings":"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"}
|
|
@@ -35,9 +35,26 @@ const fieldBase = {
|
|
|
35
35
|
fontWeight: 'semibold',
|
|
36
36
|
},
|
|
37
37
|
};
|
|
38
|
+
/**
|
|
39
|
+
* Room for the × and its divider at the end of the value, while the × shows.
|
|
40
|
+
*
|
|
41
|
+
* The indicator group overlays the value. Chakra keeps the value off the
|
|
42
|
+
* chevron with `maxW: 80%` on a Select (too little in a narrow filter) and a
|
|
43
|
+
* 1.5× height padding on a Combobox, and neither counts the × with its
|
|
44
|
+
* divider. This reserves the whole group instead: padding on both sides, the
|
|
45
|
+
* × (`8`) with its `me` (`1`), the group `gap` (`1`) and the chevron (`1em`),
|
|
46
|
+
* so a long value ends in an ellipsis before the ×.
|
|
47
|
+
*/
|
|
48
|
+
const clearTriggerRoom = (paddingVar) => ({
|
|
49
|
+
'[data-part=control]:has([data-part=clear-trigger]:not([hidden])) > &': {
|
|
50
|
+
pe: `calc(var(${paddingVar}) * 2 + 3.5em)`,
|
|
51
|
+
'& [data-part=value-text]': { maxW: 'none' },
|
|
52
|
+
},
|
|
53
|
+
});
|
|
38
54
|
/** Select trigger — the clickable control. */
|
|
39
55
|
const triggerStyles = {
|
|
40
56
|
...fieldBase,
|
|
57
|
+
...clearTriggerRoom('--select-trigger-padding-x'),
|
|
41
58
|
cursor: 'pointer',
|
|
42
59
|
_open: {
|
|
43
60
|
borderColor: 'primary.main',
|
|
@@ -76,6 +93,7 @@ const ghostTriggerStyles = {
|
|
|
76
93
|
/** Combobox text input — the typeable control. */
|
|
77
94
|
const inputStyles = {
|
|
78
95
|
...fieldBase,
|
|
96
|
+
...clearTriggerRoom('--combobox-input-padding-x'),
|
|
79
97
|
};
|
|
80
98
|
/** Dropdown panel for both Select and Combobox. */
|
|
81
99
|
const contentStyles = {
|
|
@@ -112,6 +130,61 @@ const itemStyles = {
|
|
|
112
130
|
const indicatorStyles = {
|
|
113
131
|
color: 'fg.muted',
|
|
114
132
|
};
|
|
133
|
+
/**
|
|
134
|
+
* Clear (×) button for both Select and Combobox.
|
|
135
|
+
*
|
|
136
|
+
* Chakra's recipe gives this part a colour and no size, and its default icon
|
|
137
|
+
* is `1em`, so a bare `ClearTrigger` drew a 21px × next to a 14px chevron. The
|
|
138
|
+
* × is the secondary action, so it is smaller (`3.5`, 12px at 14px text) and
|
|
139
|
+
* lighter (`fg.icon`) than the chevron, on an `8` box. `& svg` rather than
|
|
140
|
+
* `_icon` so the size also wins over an icon passed with its own `boxSize`.
|
|
141
|
+
*
|
|
142
|
+
* On a touch screen the hit area widens to 44px, toward the value only: the
|
|
143
|
+
* chevron sits to the right and has to keep opening the list. The height stays
|
|
144
|
+
* the control's own height (`heightVar`), so the area never reaches the field
|
|
145
|
+
* above or below. Every control height is over the 24px KWCAG minimum.
|
|
146
|
+
*/
|
|
147
|
+
const clearTriggerStyles = (heightVar) => ({
|
|
148
|
+
position: 'relative',
|
|
149
|
+
display: 'inline-flex',
|
|
150
|
+
alignItems: 'center',
|
|
151
|
+
justifyContent: 'center',
|
|
152
|
+
boxSize: '8',
|
|
153
|
+
me: '1',
|
|
154
|
+
color: 'fg.icon',
|
|
155
|
+
cursor: 'pointer',
|
|
156
|
+
_hover: { color: 'fg.default' },
|
|
157
|
+
// The divider marks where opening starts: it sits in the `me` gap, takes no
|
|
158
|
+
// clicks, and everything right of it belongs to the chevron.
|
|
159
|
+
_after: {
|
|
160
|
+
content: '""',
|
|
161
|
+
position: 'absolute',
|
|
162
|
+
insetEnd: '-1',
|
|
163
|
+
top: '50%',
|
|
164
|
+
transform: 'translateY(-50%)',
|
|
165
|
+
h: '4',
|
|
166
|
+
borderEndWidth: '1px',
|
|
167
|
+
borderColor: 'border.subtle',
|
|
168
|
+
pointerEvents: 'none',
|
|
169
|
+
},
|
|
170
|
+
// zag hides the × with the `hidden` attribute while nothing is selected,
|
|
171
|
+
// and the `display` above would otherwise override it.
|
|
172
|
+
_hidden: { display: 'none' },
|
|
173
|
+
'& svg': { width: '3.5', height: '3.5' },
|
|
174
|
+
'@media (pointer: coarse)': {
|
|
175
|
+
'&::before': {
|
|
176
|
+
content: '""',
|
|
177
|
+
position: 'absolute',
|
|
178
|
+
insetEnd: 0,
|
|
179
|
+
top: '50%',
|
|
180
|
+
transform: 'translateY(-50%)',
|
|
181
|
+
width: '44px',
|
|
182
|
+
height: `var(${heightVar})`,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
});
|
|
186
|
+
const selectClearTriggerStyles = clearTriggerStyles('--select-trigger-height');
|
|
187
|
+
const comboboxClearTriggerStyles = clearTriggerStyles('--combobox-input-height');
|
|
115
188
|
|
|
116
|
-
export { contentStyles, ghostContentStyles, ghostTriggerStyles, indicatorStyles, inputStyles, itemStyles, triggerStyles };
|
|
189
|
+
export { comboboxClearTriggerStyles, contentStyles, ghostContentStyles, ghostTriggerStyles, indicatorStyles, inputStyles, itemStyles, selectClearTriggerStyles, triggerStyles };
|
|
117
190
|
//# sourceMappingURL=Select.styles.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.styles.mjs","sources":["../../../src/components/Select/Select.styles.ts"],"sourcesContent":[null],"names":[],"mappings":";;;AAAA;;;;;;;;AAQG;AAIH,MAAM,SAAS,GAAG;AAChB,IAAA,eAAe,EAAE,mCAAmC;AACpD,IAAA,eAAe,EAAE,mCAAmC;CACrD;AAED,MAAM,SAAS,GAAG;AAChB,IAAA,GAAG,SAAS;AACZ,IAAA,EAAE,EAAE,YAAY;AAChB,IAAA,KAAK,EAAE,YAAY;AACnB,IAAA,WAAW,EAAE,gBAAgB;AAC7B,IAAA,MAAM,EAAE,EAAE,WAAW,EAAE,SAAS,EAAE;AAClC,IAAA,MAAM,EAAE;AACN,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,SAAS,EAAE,6CAA6C;AACzD,KAAA;AACD,IAAA,QAAQ,EAAE;AACR,QAAA,WAAW,EAAE,cAAc;AAC3B,QAAA,MAAM,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE;AACvC,QAAA,MAAM,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE;AACxC,KAAA;AACD,IAAA,SAAS,EAAE;AACT,QAAA,GAAG,eAAe;AAClB,QAAA,MAAM,EAAE,aAAa;AACrB,QAAA,UAAU,EAAE,UAAU;AACvB,KAAA;CACF;AAED;AACO,MAAM,aAAa,GAAG;AAC3B,IAAA,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"Select.styles.mjs","sources":["../../../src/components/Select/Select.styles.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
|
|
@@ -241,6 +241,13 @@ var close = {
|
|
|
241
241
|
ja: "閉じる",
|
|
242
242
|
es: "Cerrar"
|
|
243
243
|
};
|
|
244
|
+
var clear_selection = {
|
|
245
|
+
ko: "선택 지우기",
|
|
246
|
+
en: "Clear selection",
|
|
247
|
+
zh: "清除选择",
|
|
248
|
+
ja: "選択をクリア",
|
|
249
|
+
es: "Borrar selección"
|
|
250
|
+
};
|
|
244
251
|
var defaultTranslations = {
|
|
245
252
|
get_started: get_started,
|
|
246
253
|
next: next,
|
|
@@ -282,11 +289,13 @@ var defaultTranslations = {
|
|
|
282
289
|
downloading: downloading,
|
|
283
290
|
processing: processing,
|
|
284
291
|
deleting: deleting,
|
|
285
|
-
close: close
|
|
292
|
+
close: close,
|
|
293
|
+
clear_selection: clear_selection
|
|
286
294
|
};
|
|
287
295
|
|
|
288
296
|
exports.anonymous = anonymous;
|
|
289
297
|
exports.clear = clear;
|
|
298
|
+
exports.clear_selection = clear_selection;
|
|
290
299
|
exports.close = close;
|
|
291
300
|
exports.component = component;
|
|
292
301
|
exports.copied = copied;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Defaults.translations.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Defaults.translations.json.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -237,6 +237,13 @@ var close = {
|
|
|
237
237
|
ja: "閉じる",
|
|
238
238
|
es: "Cerrar"
|
|
239
239
|
};
|
|
240
|
+
var clear_selection = {
|
|
241
|
+
ko: "선택 지우기",
|
|
242
|
+
en: "Clear selection",
|
|
243
|
+
zh: "清除选择",
|
|
244
|
+
ja: "選択をクリア",
|
|
245
|
+
es: "Borrar selección"
|
|
246
|
+
};
|
|
240
247
|
var defaultTranslations = {
|
|
241
248
|
get_started: get_started,
|
|
242
249
|
next: next,
|
|
@@ -278,8 +285,9 @@ var defaultTranslations = {
|
|
|
278
285
|
downloading: downloading,
|
|
279
286
|
processing: processing,
|
|
280
287
|
deleting: deleting,
|
|
281
|
-
close: close
|
|
288
|
+
close: close,
|
|
289
|
+
clear_selection: clear_selection
|
|
282
290
|
};
|
|
283
291
|
|
|
284
|
-
export { anonymous, clear, close, component, copied, copy, copy_error_details, defaultTranslations as default, deleting, download, downloading, error_boundary_default_message, error_boundary_subtitle, error_boundary_title, error_details_copied, error_id, get_started, go_next_page_button, month_range_placeholder, next, page, pagination_items_per_page, pagination_range_text, previous, processing, refresh_page, see_less, see_more, support_help_text, support_information, time, try_again, unknown, upload_your_file, user_id };
|
|
292
|
+
export { anonymous, clear, clear_selection, close, component, copied, copy, copy_error_details, defaultTranslations as default, deleting, download, downloading, error_boundary_default_message, error_boundary_subtitle, error_boundary_title, error_details_copied, error_id, get_started, go_next_page_button, month_range_placeholder, next, page, pagination_items_per_page, pagination_range_text, previous, processing, refresh_page, see_less, see_more, support_help_text, support_information, time, try_again, unknown, upload_your_file, user_id };
|
|
285
293
|
//# sourceMappingURL=Defaults.translations.json.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Defaults.translations.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Defaults.translations.json.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { forwardRef } from 'react';
|
|
2
2
|
import { Combobox as ChakraCombobox } from '@chakra-ui/react';
|
|
3
3
|
|
|
4
|
+
import { useTranslate } from '@/hooks/useTranslate';
|
|
4
5
|
import { noZoomOnFocus } from '@/theme/formControls';
|
|
5
6
|
import { mergeCss } from '@/utils/mergeCss';
|
|
6
7
|
|
|
7
|
-
import {
|
|
8
|
+
import { CloseIcon } from '../Icon';
|
|
9
|
+
import {
|
|
10
|
+
comboboxClearTriggerStyles,
|
|
11
|
+
contentStyles,
|
|
12
|
+
inputStyles,
|
|
13
|
+
itemStyles,
|
|
14
|
+
} from './Select.styles';
|
|
8
15
|
|
|
9
16
|
const Input = forwardRef<HTMLInputElement, ChakraCombobox.InputProps>(
|
|
10
17
|
function ComboboxInput({ css, ...props }, ref) {
|
|
@@ -47,10 +54,28 @@ const Item = forwardRef<HTMLDivElement, ChakraCombobox.ItemProps>(
|
|
|
47
54
|
}
|
|
48
55
|
);
|
|
49
56
|
|
|
57
|
+
/** Same × as `Select.ClearTrigger`; see there. */
|
|
58
|
+
const ClearTrigger = forwardRef<
|
|
59
|
+
HTMLButtonElement,
|
|
60
|
+
ChakraCombobox.ClearTriggerProps
|
|
61
|
+
>(function ComboboxClearTrigger({ css, children, ...props }, ref) {
|
|
62
|
+
const translate = useTranslate();
|
|
63
|
+
return (
|
|
64
|
+
<ChakraCombobox.ClearTrigger
|
|
65
|
+
ref={ref}
|
|
66
|
+
aria-label={translate('clear_selection') as string}
|
|
67
|
+
{...props}
|
|
68
|
+
css={mergeCss(comboboxClearTriggerStyles, css)}
|
|
69
|
+
>
|
|
70
|
+
{children ?? <CloseIcon aria-hidden />}
|
|
71
|
+
</ChakraCombobox.ClearTrigger>
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
50
75
|
/**
|
|
51
76
|
* Compound Combobox primitives — Chakra's `Combobox` namespace with the
|
|
52
77
|
* Logician design-system styling baked into the visual parts (`Input`,
|
|
53
|
-
* `Content`, `Item`). Use these directly for full compositional control;
|
|
78
|
+
* `Content`, `Item`, `ClearTrigger`). Use these directly for full compositional control;
|
|
54
79
|
* use `ComboboxField` for the common single-select case.
|
|
55
80
|
*/
|
|
56
81
|
export const Combobox = {
|
|
@@ -62,7 +87,7 @@ export const Combobox = {
|
|
|
62
87
|
Input,
|
|
63
88
|
Trigger: ChakraCombobox.Trigger,
|
|
64
89
|
IndicatorGroup: ChakraCombobox.IndicatorGroup,
|
|
65
|
-
ClearTrigger
|
|
90
|
+
ClearTrigger,
|
|
66
91
|
Positioner: ChakraCombobox.Positioner,
|
|
67
92
|
Content,
|
|
68
93
|
Empty: ChakraCombobox.Empty,
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { ChakraProvider, createListCollection } from '@chakra-ui/react';
|
|
2
|
+
import { fireEvent, render, screen, waitFor } from '@testing-library/react';
|
|
3
|
+
import { describe, expect, it, vi } from 'vitest';
|
|
4
|
+
|
|
5
|
+
import { system } from '../../theme';
|
|
6
|
+
import { Select } from './Select';
|
|
7
|
+
|
|
8
|
+
const collection = createListCollection({
|
|
9
|
+
items: [
|
|
10
|
+
{ label: 'React', value: 'react' },
|
|
11
|
+
{ label: 'Vue', value: 'vue' },
|
|
12
|
+
],
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
const renderClearable = (
|
|
16
|
+
clearTrigger: React.ReactNode,
|
|
17
|
+
onValueChange = vi.fn(),
|
|
18
|
+
defaultValue = ['react']
|
|
19
|
+
) =>
|
|
20
|
+
render(
|
|
21
|
+
<ChakraProvider value={system}>
|
|
22
|
+
<Select.Root
|
|
23
|
+
collection={collection}
|
|
24
|
+
defaultValue={defaultValue}
|
|
25
|
+
onValueChange={onValueChange}
|
|
26
|
+
>
|
|
27
|
+
<Select.HiddenSelect />
|
|
28
|
+
<Select.Control>
|
|
29
|
+
<Select.Trigger>
|
|
30
|
+
<Select.ValueText />
|
|
31
|
+
</Select.Trigger>
|
|
32
|
+
<Select.IndicatorGroup>
|
|
33
|
+
{clearTrigger}
|
|
34
|
+
<Select.Indicator />
|
|
35
|
+
</Select.IndicatorGroup>
|
|
36
|
+
</Select.Control>
|
|
37
|
+
</Select.Root>
|
|
38
|
+
</ChakraProvider>
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
describe('Select.ClearTrigger', () => {
|
|
42
|
+
it('names itself in the library language instead of "Clear value"', () => {
|
|
43
|
+
renderClearable(<Select.ClearTrigger />);
|
|
44
|
+
|
|
45
|
+
const button = screen.getByRole('button', { name: '선택 지우기' });
|
|
46
|
+
expect(button.querySelector('svg')).not.toBeNull();
|
|
47
|
+
expect(screen.queryByRole('button', { name: 'Clear value' })).toBeNull();
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it("keeps the caller's aria-label and still clears the value", async () => {
|
|
51
|
+
const onValueChange = vi.fn();
|
|
52
|
+
renderClearable(
|
|
53
|
+
<Select.ClearTrigger aria-label="조직 선택 지우기" />,
|
|
54
|
+
onValueChange
|
|
55
|
+
);
|
|
56
|
+
|
|
57
|
+
fireEvent.click(screen.getByRole('button', { name: '조직 선택 지우기' }));
|
|
58
|
+
|
|
59
|
+
await waitFor(() =>
|
|
60
|
+
expect(onValueChange).toHaveBeenCalledWith(
|
|
61
|
+
expect.objectContaining({ value: [] })
|
|
62
|
+
)
|
|
63
|
+
);
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
it('stays hidden while nothing is selected', () => {
|
|
67
|
+
renderClearable(<Select.ClearTrigger />, vi.fn(), []);
|
|
68
|
+
|
|
69
|
+
const button = document.querySelector<HTMLElement>(
|
|
70
|
+
'[data-part="clear-trigger"]'
|
|
71
|
+
);
|
|
72
|
+
expect(button).not.toBeNull();
|
|
73
|
+
expect(button).toHaveAttribute('hidden');
|
|
74
|
+
expect(getComputedStyle(button!).display).toBe('none');
|
|
75
|
+
});
|
|
76
|
+
});
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
contentStyles,
|
|
23
23
|
indicatorStyles,
|
|
24
24
|
itemStyles,
|
|
25
|
+
selectClearTriggerStyles,
|
|
25
26
|
triggerStyles,
|
|
26
27
|
} from './Select.styles';
|
|
27
28
|
import { SelectField } from './SelectField';
|
|
@@ -198,6 +199,76 @@ export const MultiSelect = () => (
|
|
|
198
199
|
</Box>
|
|
199
200
|
);
|
|
200
201
|
|
|
202
|
+
/**
|
|
203
|
+
* An optional field the member can empty again. `ClearTrigger` goes before
|
|
204
|
+
* the chevron and shows only while something is selected. It draws its own
|
|
205
|
+
* icon and is named 「선택 지우기」 in the provider's language; pass
|
|
206
|
+
* `aria-label` to say what is cleared. A divider separates it from the
|
|
207
|
+
* chevron, and a long value ends in an ellipsis before it. On a touch screen
|
|
208
|
+
* its hit area widens to 44px toward the value, at the field's own height.
|
|
209
|
+
*/
|
|
210
|
+
const longValueCollection = createListCollection({
|
|
211
|
+
items: [
|
|
212
|
+
{
|
|
213
|
+
label: 'Engineering / Platform / Developer Experience',
|
|
214
|
+
value: 'dx',
|
|
215
|
+
},
|
|
216
|
+
{ label: 'Design', value: 'design' },
|
|
217
|
+
],
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
export const Clearable = () => (
|
|
221
|
+
<Stack maxW="320px" gap={4}>
|
|
222
|
+
<Box maxW="180px">
|
|
223
|
+
<Select.Root collection={longValueCollection} defaultValue={['dx']}>
|
|
224
|
+
<Select.HiddenSelect />
|
|
225
|
+
<Select.Label>Team (180px)</Select.Label>
|
|
226
|
+
<Select.Control>
|
|
227
|
+
<Select.Trigger>
|
|
228
|
+
<Select.ValueText placeholder="Select a team" />
|
|
229
|
+
</Select.Trigger>
|
|
230
|
+
<Select.IndicatorGroup>
|
|
231
|
+
<Select.ClearTrigger />
|
|
232
|
+
<Select.Indicator />
|
|
233
|
+
</Select.IndicatorGroup>
|
|
234
|
+
</Select.Control>
|
|
235
|
+
</Select.Root>
|
|
236
|
+
</Box>
|
|
237
|
+
{(['xs', 'sm', 'md', 'lg'] as const).map((size) => (
|
|
238
|
+
<Select.Root
|
|
239
|
+
key={size}
|
|
240
|
+
size={size}
|
|
241
|
+
collection={frameworkCollection}
|
|
242
|
+
defaultValue={['react']}
|
|
243
|
+
>
|
|
244
|
+
<Select.HiddenSelect />
|
|
245
|
+
<Select.Label>{`Framework (${size})`}</Select.Label>
|
|
246
|
+
<Select.Control>
|
|
247
|
+
<Select.Trigger>
|
|
248
|
+
<Select.ValueText placeholder="Select a framework" />
|
|
249
|
+
</Select.Trigger>
|
|
250
|
+
<Select.IndicatorGroup>
|
|
251
|
+
<Select.ClearTrigger />
|
|
252
|
+
<Select.Indicator />
|
|
253
|
+
</Select.IndicatorGroup>
|
|
254
|
+
</Select.Control>
|
|
255
|
+
<Portal>
|
|
256
|
+
<Select.Positioner>
|
|
257
|
+
<Select.Content>
|
|
258
|
+
{frameworkCollection.items.map((item) => (
|
|
259
|
+
<Select.Item item={item} key={item.value}>
|
|
260
|
+
<Select.ItemText>{item.label}</Select.ItemText>
|
|
261
|
+
<Select.ItemIndicator />
|
|
262
|
+
</Select.Item>
|
|
263
|
+
))}
|
|
264
|
+
</Select.Content>
|
|
265
|
+
</Select.Positioner>
|
|
266
|
+
</Portal>
|
|
267
|
+
</Select.Root>
|
|
268
|
+
))}
|
|
269
|
+
</Stack>
|
|
270
|
+
);
|
|
271
|
+
|
|
201
272
|
/* -------------------------------------------------------------------------
|
|
202
273
|
* Custom children
|
|
203
274
|
*
|
|
@@ -950,6 +1021,16 @@ export const UsageTokens: UsageStory = {
|
|
|
950
1021
|
token: indicatorStyles.color,
|
|
951
1022
|
use: <T en="Chevron" ko="펼침 화살표" />,
|
|
952
1023
|
},
|
|
1024
|
+
{
|
|
1025
|
+
token: selectClearTriggerStyles.color,
|
|
1026
|
+
use: <T en="Clear (×) button" ko="선택 지우기(×) 버튼" />,
|
|
1027
|
+
},
|
|
1028
|
+
{
|
|
1029
|
+
token: selectClearTriggerStyles._hover.color,
|
|
1030
|
+
use: (
|
|
1031
|
+
<T en="Clear button on hover" ko="마우스를 올렸을 때 지우기 버튼" />
|
|
1032
|
+
),
|
|
1033
|
+
},
|
|
953
1034
|
{
|
|
954
1035
|
token: contentStyles.bg,
|
|
955
1036
|
use: <T en="List background" ko="목록 배경" />,
|
|
@@ -37,9 +37,27 @@ const fieldBase = {
|
|
|
37
37
|
},
|
|
38
38
|
};
|
|
39
39
|
|
|
40
|
+
/**
|
|
41
|
+
* Room for the × and its divider at the end of the value, while the × shows.
|
|
42
|
+
*
|
|
43
|
+
* The indicator group overlays the value. Chakra keeps the value off the
|
|
44
|
+
* chevron with `maxW: 80%` on a Select (too little in a narrow filter) and a
|
|
45
|
+
* 1.5× height padding on a Combobox, and neither counts the × with its
|
|
46
|
+
* divider. This reserves the whole group instead: padding on both sides, the
|
|
47
|
+
* × (`8`) with its `me` (`1`), the group `gap` (`1`) and the chevron (`1em`),
|
|
48
|
+
* so a long value ends in an ellipsis before the ×.
|
|
49
|
+
*/
|
|
50
|
+
const clearTriggerRoom = (paddingVar: string) => ({
|
|
51
|
+
'[data-part=control]:has([data-part=clear-trigger]:not([hidden])) > &': {
|
|
52
|
+
pe: `calc(var(${paddingVar}) * 2 + 3.5em)`,
|
|
53
|
+
'& [data-part=value-text]': { maxW: 'none' },
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
40
57
|
/** Select trigger — the clickable control. */
|
|
41
58
|
export const triggerStyles = {
|
|
42
59
|
...fieldBase,
|
|
60
|
+
...clearTriggerRoom('--select-trigger-padding-x'),
|
|
43
61
|
cursor: 'pointer',
|
|
44
62
|
_open: {
|
|
45
63
|
borderColor: 'primary.main',
|
|
@@ -80,6 +98,7 @@ export const ghostTriggerStyles = {
|
|
|
80
98
|
/** Combobox text input — the typeable control. */
|
|
81
99
|
export const inputStyles = {
|
|
82
100
|
...fieldBase,
|
|
101
|
+
...clearTriggerRoom('--combobox-input-padding-x'),
|
|
83
102
|
};
|
|
84
103
|
|
|
85
104
|
/** Dropdown panel for both Select and Combobox. */
|
|
@@ -120,3 +139,65 @@ export const itemStyles = {
|
|
|
120
139
|
export const indicatorStyles = {
|
|
121
140
|
color: 'fg.muted',
|
|
122
141
|
};
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Clear (×) button for both Select and Combobox.
|
|
145
|
+
*
|
|
146
|
+
* Chakra's recipe gives this part a colour and no size, and its default icon
|
|
147
|
+
* is `1em`, so a bare `ClearTrigger` drew a 21px × next to a 14px chevron. The
|
|
148
|
+
* × is the secondary action, so it is smaller (`3.5`, 12px at 14px text) and
|
|
149
|
+
* lighter (`fg.icon`) than the chevron, on an `8` box. `& svg` rather than
|
|
150
|
+
* `_icon` so the size also wins over an icon passed with its own `boxSize`.
|
|
151
|
+
*
|
|
152
|
+
* On a touch screen the hit area widens to 44px, toward the value only: the
|
|
153
|
+
* chevron sits to the right and has to keep opening the list. The height stays
|
|
154
|
+
* the control's own height (`heightVar`), so the area never reaches the field
|
|
155
|
+
* above or below. Every control height is over the 24px KWCAG minimum.
|
|
156
|
+
*/
|
|
157
|
+
const clearTriggerStyles = (heightVar: string) => ({
|
|
158
|
+
position: 'relative',
|
|
159
|
+
display: 'inline-flex',
|
|
160
|
+
alignItems: 'center',
|
|
161
|
+
justifyContent: 'center',
|
|
162
|
+
boxSize: '8',
|
|
163
|
+
me: '1',
|
|
164
|
+
color: 'fg.icon',
|
|
165
|
+
cursor: 'pointer',
|
|
166
|
+
_hover: { color: 'fg.default' },
|
|
167
|
+
// The divider marks where opening starts: it sits in the `me` gap, takes no
|
|
168
|
+
// clicks, and everything right of it belongs to the chevron.
|
|
169
|
+
_after: {
|
|
170
|
+
content: '""',
|
|
171
|
+
position: 'absolute',
|
|
172
|
+
insetEnd: '-1',
|
|
173
|
+
top: '50%',
|
|
174
|
+
transform: 'translateY(-50%)',
|
|
175
|
+
h: '4',
|
|
176
|
+
borderEndWidth: '1px',
|
|
177
|
+
borderColor: 'border.subtle',
|
|
178
|
+
pointerEvents: 'none',
|
|
179
|
+
},
|
|
180
|
+
// zag hides the × with the `hidden` attribute while nothing is selected,
|
|
181
|
+
// and the `display` above would otherwise override it.
|
|
182
|
+
_hidden: { display: 'none' },
|
|
183
|
+
'& svg': { width: '3.5', height: '3.5' },
|
|
184
|
+
'@media (pointer: coarse)': {
|
|
185
|
+
'&::before': {
|
|
186
|
+
content: '""',
|
|
187
|
+
position: 'absolute',
|
|
188
|
+
insetEnd: 0,
|
|
189
|
+
top: '50%',
|
|
190
|
+
transform: 'translateY(-50%)',
|
|
191
|
+
width: '44px',
|
|
192
|
+
height: `var(${heightVar})`,
|
|
193
|
+
},
|
|
194
|
+
},
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
export const selectClearTriggerStyles = clearTriggerStyles(
|
|
198
|
+
'--select-trigger-height'
|
|
199
|
+
);
|
|
200
|
+
|
|
201
|
+
export const comboboxClearTriggerStyles = clearTriggerStyles(
|
|
202
|
+
'--combobox-input-height'
|
|
203
|
+
);
|
|
@@ -1,13 +1,16 @@
|
|
|
1
1
|
import { forwardRef } from 'react';
|
|
2
2
|
import { Select as ChakraSelect } from '@chakra-ui/react';
|
|
3
3
|
|
|
4
|
+
import { useTranslate } from '@/hooks/useTranslate';
|
|
4
5
|
import { mergeCss } from '@/utils/mergeCss';
|
|
5
6
|
|
|
7
|
+
import { CloseIcon } from '../Icon';
|
|
6
8
|
import {
|
|
7
9
|
contentStyles,
|
|
8
10
|
ghostTriggerStyles,
|
|
9
11
|
indicatorStyles,
|
|
10
12
|
itemStyles,
|
|
13
|
+
selectClearTriggerStyles,
|
|
11
14
|
triggerStyles,
|
|
12
15
|
} from './Select.styles';
|
|
13
16
|
import type { SelectVariant } from './Select.types';
|
|
@@ -67,10 +70,33 @@ const Indicator = forwardRef<HTMLDivElement, ChakraSelect.IndicatorProps>(
|
|
|
67
70
|
}
|
|
68
71
|
);
|
|
69
72
|
|
|
73
|
+
/**
|
|
74
|
+
* The × that empties the selection. Draws `CloseIcon` when no children are
|
|
75
|
+
* passed, and names itself in the provider's language: Chakra's own name is
|
|
76
|
+
* the English "Clear value" in every locale. Pass `aria-label` to say what is
|
|
77
|
+
* being cleared ("조직 선택 지우기").
|
|
78
|
+
*/
|
|
79
|
+
const ClearTrigger = forwardRef<
|
|
80
|
+
HTMLButtonElement,
|
|
81
|
+
ChakraSelect.ClearTriggerProps
|
|
82
|
+
>(function SelectClearTrigger({ css, children, ...props }, ref) {
|
|
83
|
+
const translate = useTranslate();
|
|
84
|
+
return (
|
|
85
|
+
<ChakraSelect.ClearTrigger
|
|
86
|
+
ref={ref}
|
|
87
|
+
aria-label={translate('clear_selection') as string}
|
|
88
|
+
{...props}
|
|
89
|
+
css={mergeCss(selectClearTriggerStyles, css)}
|
|
90
|
+
>
|
|
91
|
+
{children ?? <CloseIcon aria-hidden />}
|
|
92
|
+
</ChakraSelect.ClearTrigger>
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
|
|
70
96
|
/**
|
|
71
97
|
* Compound Select primitives — Chakra's `Select` namespace with the Logician
|
|
72
98
|
* design-system styling baked into the visual parts (`Trigger`, `Content`,
|
|
73
|
-
* `Item`, `Indicator`). Use these directly for full compositional control
|
|
99
|
+
* `Item`, `Indicator`, `ClearTrigger`). Use these directly for full compositional control
|
|
74
100
|
* (multi-select, grouped options, custom layouts); use `SelectField` for the
|
|
75
101
|
* common single-select case.
|
|
76
102
|
*/
|
|
@@ -84,7 +110,7 @@ export const Select = {
|
|
|
84
110
|
ValueText: ChakraSelect.ValueText,
|
|
85
111
|
IndicatorGroup: ChakraSelect.IndicatorGroup,
|
|
86
112
|
Indicator,
|
|
87
|
-
ClearTrigger
|
|
113
|
+
ClearTrigger,
|
|
88
114
|
HiddenSelect: ChakraSelect.HiddenSelect,
|
|
89
115
|
Positioner: ChakraSelect.Positioner,
|
|
90
116
|
Content,
|
|
@@ -96,6 +96,32 @@ Other props: `size` (`xs`–`lg`, default `md`), `invalid`, `disabled`,
|
|
|
96
96
|
`null` when the selection is cleared. `ComboboxField` adds `emptyText`; it has
|
|
97
97
|
no `variant` or `stagger`.
|
|
98
98
|
|
|
99
|
+
## Clearing the value
|
|
100
|
+
|
|
101
|
+
When "nothing chosen" is a valid value, let the user empty the field again: a
|
|
102
|
+
filter, or a form field that is not required. Do not offer it on a required
|
|
103
|
+
field.
|
|
104
|
+
|
|
105
|
+
`ComboboxField` already has the button. `SelectField` has none, so a
|
|
106
|
+
clearable select is composed from `Select.*`. With `Select.*` or
|
|
107
|
+
`Combobox.*`, put `ClearTrigger` in the indicator group, before the chevron:
|
|
108
|
+
|
|
109
|
+
```tsx
|
|
110
|
+
<Select.IndicatorGroup>
|
|
111
|
+
<Select.ClearTrigger aria-label="조직 선택 지우기" />
|
|
112
|
+
<Select.Indicator />
|
|
113
|
+
</Select.IndicatorGroup>
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
The part does the rest. It shows only while something is selected. It draws
|
|
117
|
+
its own icon, smaller and lighter than the chevron, with a divider between
|
|
118
|
+
them. While it shows, the value ends in an ellipsis before it. On a touch
|
|
119
|
+
screen its hit area widens to 44px toward the value, at the field's own
|
|
120
|
+
height. Do not pass a size, a colour or your own divider.
|
|
121
|
+
|
|
122
|
+
`onValueChange` receives an empty value when it is pressed;
|
|
123
|
+
`ComboboxField` passes `null` to `onChange`.
|
|
124
|
+
|
|
99
125
|
## Do / Don't
|
|
100
126
|
|
|
101
127
|
</En>
|
|
@@ -112,6 +138,30 @@ no `variant` or `stagger`.
|
|
|
112
138
|
받습니다. `ComboboxField`에는 `emptyText`가 더 있고, `variant`와 `stagger`는
|
|
113
139
|
없습니다.
|
|
114
140
|
|
|
141
|
+
## 선택 지우기
|
|
142
|
+
|
|
143
|
+
"아무것도 고르지 않음"도 올바른 값일 때는 사용자가 필드를 다시 비울 수 있게 합니다.
|
|
144
|
+
필터나 필수가 아닌 폼 필드가 그렇습니다. 필수 필드에는 두지 않습니다.
|
|
145
|
+
|
|
146
|
+
`ComboboxField`에는 이미 들어 있습니다. `SelectField`에는 없으므로, 지울 수 있는
|
|
147
|
+
셀렉트는 `Select.*`로 조합합니다. `Select.*`나 `Combobox.*`로 조합할 때는
|
|
148
|
+
`ClearTrigger`를 indicator group 안, 화살표 앞에 둡니다.
|
|
149
|
+
|
|
150
|
+
```tsx
|
|
151
|
+
<Select.IndicatorGroup>
|
|
152
|
+
<Select.ClearTrigger aria-label="조직 선택 지우기" />
|
|
153
|
+
<Select.Indicator />
|
|
154
|
+
</Select.IndicatorGroup>
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
나머지는 부품이 처리합니다. 무언가 골라져 있을 때만 보입니다. 아이콘을 직접 그리고,
|
|
158
|
+
화살표보다 작고 옅게 그리며, 화살표와의 사이에 구분선을 둡니다. 보이는 동안 값은
|
|
159
|
+
버튼 앞에서 말줄임으로 끝납니다. 터치 화면에서는 누르는 영역이 값 쪽으로 44px까지
|
|
160
|
+
넓어지고, 높이는 필드 높이를 따릅니다. 크기, 색, 구분선을 따로 넘기지 마세요.
|
|
161
|
+
|
|
162
|
+
누르면 `onValueChange`가 빈 값을 받습니다. `ComboboxField`는 `onChange`에
|
|
163
|
+
`null`을 넘깁니다.
|
|
164
|
+
|
|
115
165
|
## 이렇게 하세요 / 이렇게 하지 마세요
|
|
116
166
|
|
|
117
167
|
</Ko>
|
|
@@ -144,6 +194,13 @@ no `variant` or `stagger`.
|
|
|
144
194
|
ko="사용자가 이름을 알고 목록이 길다면 ComboboxField를 씁니다. emptyText의 기본값은 영어이므로 번역해서 넘깁니다."
|
|
145
195
|
/>
|
|
146
196
|
|
|
197
|
+
<Canvas of={SelectStories.Clearable} />
|
|
198
|
+
<Verdict
|
|
199
|
+
kind="do"
|
|
200
|
+
en="On an optional field, put ClearTrigger before the chevron and pass an aria-label that says what is cleared. Without one it is named 'Clear selection' in the provider language."
|
|
201
|
+
ko="필수가 아닌 필드에는 화살표 앞에 ClearTrigger를 두고, 무엇을 지우는지 aria-label로 넘깁니다. 넘기지 않으면 provider 언어의 '선택 지우기'로 읽힙니다."
|
|
202
|
+
/>
|
|
203
|
+
|
|
147
204
|
<Canvas of={SelectStories.DontSelectForTwo} />
|
|
148
205
|
<Verdict
|
|
149
206
|
kind="dont"
|
|
@@ -183,6 +240,9 @@ What these components do for you:
|
|
|
183
240
|
- **Keyboard.** The Chakra / Zag listbox handles it: Enter, Space or the arrow
|
|
184
241
|
keys open the list; arrows move; Enter selects; Escape closes and returns
|
|
185
242
|
focus to the trigger. In `ComboboxField` typing filters the list.
|
|
243
|
+
- **A name for the clear button.** `ClearTrigger` is named 「선택 지우기」 /
|
|
244
|
+
"Clear selection" in the provider language, instead of Chakra's English
|
|
245
|
+
"Clear value" in every locale. A caller's `aria-label` wins.
|
|
186
246
|
- **Focus and states.** The trigger shows a `primary.main` border and ring on
|
|
187
247
|
focus and while open (WCAG 2.4.7). The selected option is bold on
|
|
188
248
|
`primary.selected` and carries a check mark, so it does not rely on colour
|
|
@@ -228,6 +288,9 @@ Generated from `Select.styles.ts`. Select and Combobox share these.
|
|
|
228
288
|
- **키보드.** Chakra와 Zag의 목록 상자가 처리합니다. Enter, Space, 방향키로 목록을
|
|
229
289
|
열고, 방향키로 옮기고, Enter로 고르며, Escape로 닫으면 초점이 트리거로 돌아갑니다.
|
|
230
290
|
`ComboboxField`에서는 입력하면 목록이 걸러집니다.
|
|
291
|
+
- **지우기 버튼의 이름.** `ClearTrigger`는 provider 언어로 「선택 지우기」
|
|
292
|
+
("Clear selection")라는 이름을 가집니다. Chakra 기본값은 어느 언어에서나 영어
|
|
293
|
+
"Clear value"였습니다. 호출부에서 넘긴 `aria-label`이 우선합니다.
|
|
231
294
|
- **초점과 상태.** 트리거는 초점을 받거나 열려 있는 동안 `primary.main` 테두리와 링을
|
|
232
295
|
보여 줍니다(WCAG 2.4.7). 선택된 항목은 `primary.selected` 위에 굵은 글자와 체크
|
|
233
296
|
표시로 나타나므로 색에만 기대지 않습니다(WCAG 1.4.1).
|