@drivenets/design-system 0.19.0 → 0.20.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.
- package/CHANGELOG.md +28 -0
- package/dist/index.cjs +12409 -10548
- package/dist/index.d.cts +678 -312
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +679 -313
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +12404 -10550
- package/dist/index.js.map +1 -1
- package/dist/index.min.css +1 -1
- package/package.json +29 -29
- package/src/components/ds-checkbox/ds-checkbox.figma.ts +3 -0
- package/src/components/ds-checkbox/ds-checkbox.module.scss +102 -20
- package/src/components/ds-checkbox/ds-checkbox.tsx +30 -2
- package/src/components/ds-checkbox/ds-checkbox.types.ts +10 -0
- package/src/components/ds-code-input/collapsed-code-field/collapsed-code-field.module.scss +169 -0
- package/src/components/ds-code-input/collapsed-code-field/collapsed-code-field.tsx +92 -0
- package/src/components/ds-code-input/collapsed-code-field/index.ts +1 -0
- package/src/components/ds-code-input/ds-code-input-panel/ds-code-input-panel.module.scss +110 -0
- package/src/components/ds-code-input/ds-code-input-panel/ds-code-input-panel.tsx +61 -0
- package/src/components/ds-code-input/ds-code-input-panel/index.ts +1 -0
- package/src/components/ds-code-input/ds-code-input.module.scss +25 -0
- package/src/components/ds-code-input/ds-code-input.tsx +401 -0
- package/src/components/ds-code-input/ds-code-input.types.ts +166 -0
- package/src/components/ds-code-input/ds-code-input.utils.ts +94 -0
- package/src/components/ds-code-input/ds-code-input.utils.unit.test.ts +166 -0
- package/src/components/ds-code-input/index.ts +2 -0
- package/src/components/ds-code-input/use-collapsed-viewport.ts +289 -0
- package/src/components/ds-code-input/use-editor-host.ts +87 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-builder/ds-filters-bar-builder.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-builder/ds-filters-bar-builder.types.ts +41 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-builder/index.ts +1 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-clear-all.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/ds-filters-bar-conditions.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/ds-filters-bar-conditions.types.ts +30 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-conditions/index.ts +1 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-pinned.ts +31 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-query/ds-filters-bar-query.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-query/ds-filters-bar-query.types.ts +22 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-query/index.ts +1 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-saved-filters.ts +19 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-search.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-summary.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-toolbar.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-view-switch.ts +11 -0
- package/src/components/ds-filters-bar/components/ds-filters-bar-view.ts +11 -0
- package/src/components/ds-filters-bar/components/index.ts +11 -0
- package/src/components/ds-filters-bar/ds-filters-bar.context.ts +69 -0
- package/src/components/ds-filters-bar/ds-filters-bar.tsx +120 -0
- package/src/components/ds-filters-bar/ds-filters-bar.types.ts +440 -0
- package/src/components/ds-filters-bar/ds-filters-bar.unit.test.ts +216 -0
- package/src/components/ds-filters-bar/ds-filters-bar.utils.ts +141 -0
- package/src/components/ds-filters-bar/index.ts +1 -0
- package/src/components/ds-form-control/ds-form-control.module.scss +18 -0
- package/src/components/ds-form-control/ds-form-control.tsx +43 -9
- package/src/components/ds-form-control/ds-form-control.types.ts +2 -1
- package/src/components/ds-icon/custom-icons/index.ts +2 -0
- package/src/components/ds-icon/custom-icons/special-adv-filters.tsx +28 -0
- package/src/components/ds-pin-toggle/ds-pin-toggle.figma.ts +27 -0
- package/src/components/ds-pin-toggle/ds-pin-toggle.module.scss +41 -0
- package/src/components/ds-pin-toggle/ds-pin-toggle.tsx +43 -0
- package/src/components/ds-pin-toggle/ds-pin-toggle.types.ts +29 -0
- package/src/components/ds-pin-toggle/index.ts +2 -0
- package/src/components/ds-popover/components/popover-trigger/index.ts +1 -0
- package/src/components/ds-popover/components/popover-trigger/popover-trigger.tsx +15 -0
- package/src/components/ds-popover/ds-popover.context.ts +18 -0
- package/src/components/ds-popover/ds-popover.hover-intent.ts +65 -0
- package/src/components/ds-popover/ds-popover.tsx +163 -41
- package/src/components/ds-popover/ds-popover.types.ts +59 -1
- package/src/components/ds-popover/ds-popover.utils.ts +60 -0
- package/src/components/ds-popover/ds-popover.utils.unit.test.ts +25 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-delete-confirm.tsx +53 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-name-entry.tsx +64 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-name-modal.tsx +50 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-row/ds-saved-filters-row.module.scss +68 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-row/ds-saved-filters-row.tsx +83 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-row/index.ts +1 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-save.tsx +164 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/ds-saved-filters-trigger.module.scss +21 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/ds-saved-filters-trigger.tsx +237 -0
- package/src/components/ds-saved-filters/components/ds-saved-filters-trigger/index.ts +1 -0
- package/src/components/ds-saved-filters/components/index.ts +2 -0
- package/src/components/ds-saved-filters/ds-saved-filters.ts +6 -0
- package/src/components/ds-saved-filters/ds-saved-filters.types.ts +106 -0
- package/src/components/ds-saved-filters/ds-saved-filters.utils.ts +35 -0
- package/src/components/ds-saved-filters/hooks/index.ts +1 -0
- package/src/components/ds-saved-filters/hooks/use-picker-outside-dismiss.ts +42 -0
- package/src/components/ds-saved-filters/index.ts +2 -0
- package/src/components/ds-segment-group/ds-segment-group.module.scss +65 -37
- package/src/components/ds-segment-group/ds-segment-group.tsx +17 -5
- package/src/components/ds-segment-group/ds-segment-group.types.ts +20 -5
- package/src/components/ds-segment-group/figma/ds-segment-group-v2-item.figma.ts +109 -0
- package/src/components/ds-segment-group/figma/ds-segment-group-v2.figma.ts +31 -0
- package/src/components/ds-tag/ds-tag.figma.ts +23 -3
- package/src/components/ds-tag/ds-tag.module.scss +71 -7
- package/src/components/ds-tag/ds-tag.tsx +115 -14
- package/src/components/ds-tag/ds-tag.types.ts +70 -3
- package/src/components/ds-tag/ds-tag.unit.test.ts +23 -4
- package/src/components/ds-tag/index.ts +2 -2
- package/src/components/ds-text-input/ds-input-field-v02.figma.ts +2 -0
- package/src/components/ds-toggle/ds-toggle.tsx +19 -15
- package/src/components/ds-toggle/ds-toggle.types.ts +6 -0
- package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.module.scss +69 -0
- package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.tsx +55 -0
- package/src/components/ds-toggle-filter-data/ds-toggle-filter-data.types.ts +43 -0
- package/src/components/ds-toggle-filter-data/index.ts +1 -0
- package/src/components/ds-tooltip/ds-tooltip.module.scss +8 -0
- package/src/components/ds-tooltip/ds-tooltip.tsx +1 -1
- package/src/components/ds-tree/ds-tree.tsx +10 -10
- package/src/components/ds-tree/ds-tree.types.ts +40 -7
- package/src/index.ts +2 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@drivenets/design-system",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.20.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"types": "./dist/index.d.cts",
|
|
@@ -60,28 +60,30 @@
|
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@arethetypeswrong/cli": "^0.18.5",
|
|
63
|
+
"@drivenets/eslint-plugin-internal": "0.0.0",
|
|
64
|
+
"@drivenets/vite-plugin-design-system": "0.0.12",
|
|
63
65
|
"@eslint/compat": "^2.1.1",
|
|
64
|
-
"@faker-js/faker": "^10.
|
|
65
|
-
"@figma/code-connect": "^
|
|
66
|
-
"@github-ui/storybook-addon-performance-panel": "^1.
|
|
67
|
-
"@hookform/resolvers": "^5.
|
|
66
|
+
"@faker-js/faker": "^10.6.0",
|
|
67
|
+
"@figma/code-connect": "^2.0.0",
|
|
68
|
+
"@github-ui/storybook-addon-performance-panel": "^1.2.0",
|
|
69
|
+
"@hookform/resolvers": "^5.9.1",
|
|
68
70
|
"@rolldown/plugin-babel": "^0.2.3",
|
|
69
|
-
"@storybook/addon-a11y": "^10.
|
|
70
|
-
"@storybook/addon-docs": "^10.
|
|
71
|
-
"@storybook/addon-mcp": "^
|
|
72
|
-
"@storybook/addon-vitest": "^10.
|
|
73
|
-
"@storybook/react-vite": "^10.
|
|
74
|
-
"@tanstack/react-query": "^5.
|
|
75
|
-
"@tanstack/react-router": "^1.170.
|
|
76
|
-
"@tsdown/css": "^0.
|
|
71
|
+
"@storybook/addon-a11y": "^10.6.0",
|
|
72
|
+
"@storybook/addon-docs": "^10.6.0",
|
|
73
|
+
"@storybook/addon-mcp": "^10.6.0",
|
|
74
|
+
"@storybook/addon-vitest": "^10.6.0",
|
|
75
|
+
"@storybook/react-vite": "^10.6.0",
|
|
76
|
+
"@tanstack/react-query": "^5.102.8",
|
|
77
|
+
"@tanstack/react-router": "^1.170.32",
|
|
78
|
+
"@tsdown/css": "^0.23.0",
|
|
77
79
|
"@types/eslint-plugin-jsx-a11y": "^6.10.1",
|
|
78
|
-
"@types/react": "^19.2.
|
|
79
|
-
"@types/react-dom": "^19.2.
|
|
80
|
+
"@types/react": "^19.2.18",
|
|
81
|
+
"@types/react-dom": "^19.2.7",
|
|
80
82
|
"@types/serve-handler": "^6.1.4",
|
|
81
83
|
"@typescript/native": "npm:typescript@^7.0.2",
|
|
82
|
-
"@vitejs/plugin-react": "^6.
|
|
83
|
-
"@vitest/browser-playwright": "^
|
|
84
|
-
"@vitest/coverage-v8": "^
|
|
84
|
+
"@vitejs/plugin-react": "^6.1.1",
|
|
85
|
+
"@vitest/browser-playwright": "^5.0.0",
|
|
86
|
+
"@vitest/coverage-v8": "^5.0.0",
|
|
85
87
|
"babel-plugin-react-compiler": "^1.0.0",
|
|
86
88
|
"eslint": "^10.0.1",
|
|
87
89
|
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
@@ -89,25 +91,23 @@
|
|
|
89
91
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
90
92
|
"eslint-plugin-storybook": "^10.6.0",
|
|
91
93
|
"mockdate": "^3.0.5",
|
|
92
|
-
"playwright": "^1.
|
|
94
|
+
"playwright": "^1.63.0",
|
|
93
95
|
"publint": "^0.3.24",
|
|
94
96
|
"react": "^19.2.8",
|
|
95
97
|
"react-dom": "^19.2.8",
|
|
96
|
-
"react-hook-form": "^7.
|
|
98
|
+
"react-hook-form": "^7.87.0",
|
|
97
99
|
"remark-gfm": "^4.0.1",
|
|
98
|
-
"sass-embedded": "^1.
|
|
100
|
+
"sass-embedded": "^1.104.0",
|
|
99
101
|
"serve-handler": "^6.1.7",
|
|
100
|
-
"storybook": "^10.
|
|
101
|
-
"tsdown": "^0.
|
|
102
|
+
"storybook": "^10.6.0",
|
|
103
|
+
"tsdown": "^0.23.0",
|
|
102
104
|
"typed-scss-modules": "^8.1.1",
|
|
103
105
|
"typescript": "npm:@typescript/typescript6",
|
|
104
106
|
"typescript-plugin-css-modules": "^5.2.0",
|
|
105
|
-
"vite": "8.
|
|
106
|
-
"vitest": "^
|
|
107
|
-
"vitest-browser-react": "^2.
|
|
108
|
-
"zod": "^4.4
|
|
109
|
-
"@drivenets/eslint-plugin-internal": "0.0.0",
|
|
110
|
-
"@drivenets/vite-plugin-design-system": "0.0.11"
|
|
107
|
+
"vite": "8.2.2",
|
|
108
|
+
"vitest": "^5.0.0",
|
|
109
|
+
"vitest-browser-react": "^2.3.0",
|
|
110
|
+
"zod": "^4.5.4"
|
|
111
111
|
},
|
|
112
112
|
"scripts": {
|
|
113
113
|
"start": "storybook dev -p 6006",
|
|
@@ -28,6 +28,9 @@ const state = instance.getEnum('state', {
|
|
|
28
28
|
const checkedAttr =
|
|
29
29
|
checked === 'partial' ? 'defaultChecked="indeterminate"' : checked === 'checked' ? 'defaultChecked' : '';
|
|
30
30
|
|
|
31
|
+
// `size` is not mapped: it lives on `Structure_CheckboxV1`, while the published
|
|
32
|
+
// `DsCheckboxV3` set still exposes only `checked x state x color`. The snippet
|
|
33
|
+
// therefore emits the `medium` default until design bubbles the variant up.
|
|
31
34
|
const attrs = [
|
|
32
35
|
'label="Label"',
|
|
33
36
|
color === 'warning' ? 'variant="warning"' : '',
|
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
|
|
4
4
|
$checkbox-size: 16px;
|
|
5
5
|
$checkbox-border-radius: 2px;
|
|
6
|
+
$checkbox-border-width: 1.5px;
|
|
6
7
|
$checkbox-focus-ring-width: 2px;
|
|
8
|
+
$row-padding-medium: var(--4xs);
|
|
9
|
+
$row-padding-large: var(--xs);
|
|
7
10
|
$transition-duration: 0.2s;
|
|
8
11
|
|
|
9
12
|
.root {
|
|
@@ -11,7 +14,7 @@ $transition-duration: 0.2s;
|
|
|
11
14
|
display: inline-flex;
|
|
12
15
|
align-items: flex-start;
|
|
13
16
|
gap: var(--3xs);
|
|
14
|
-
padding:
|
|
17
|
+
padding: $row-padding-medium;
|
|
15
18
|
border-radius: $checkbox-border-radius;
|
|
16
19
|
cursor: pointer;
|
|
17
20
|
transition: background-color $transition-duration ease-in-out;
|
|
@@ -34,7 +37,7 @@ $transition-duration: 0.2s;
|
|
|
34
37
|
flex-shrink: 0;
|
|
35
38
|
width: $checkbox-size;
|
|
36
39
|
height: $checkbox-size;
|
|
37
|
-
border:
|
|
40
|
+
border: $checkbox-border-width solid var(--border-contrast);
|
|
38
41
|
border-radius: $checkbox-border-radius;
|
|
39
42
|
background-color: transparent;
|
|
40
43
|
transition:
|
|
@@ -60,7 +63,7 @@ $transition-duration: 0.2s;
|
|
|
60
63
|
}
|
|
61
64
|
|
|
62
65
|
.label {
|
|
63
|
-
@include typography.body-sm-
|
|
66
|
+
@include typography.body-sm-md;
|
|
64
67
|
line-height: normal;
|
|
65
68
|
color: var(--font-main);
|
|
66
69
|
}
|
|
@@ -103,24 +106,35 @@ $transition-duration: 0.2s;
|
|
|
103
106
|
}
|
|
104
107
|
}
|
|
105
108
|
}
|
|
106
|
-
}
|
|
107
109
|
|
|
108
|
-
// Overlay the native input over the control so `getByRole('checkbox')`
|
|
109
|
-
// land on a real interactive surface. Ark applies
|
|
110
|
-
// (1x1, clipped, off-screen) which Playwright
|
|
111
|
-
// is required to beat inline-style
|
|
112
|
-
.
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
110
|
+
// Overlay the native input over the control so `getByRole('checkbox')`
|
|
111
|
+
// clicks land on a real interactive surface. Ark applies
|
|
112
|
+
// `visuallyHiddenStyle` inline (1x1, clipped, off-screen) which Playwright
|
|
113
|
+
// refuses to click; `!important` is required to beat inline-style
|
|
114
|
+
// specificity. The control is the row's first child, so the offset is the
|
|
115
|
+
// root's own padding — which is size-dependent.
|
|
116
|
+
.hiddenInput {
|
|
117
|
+
position: absolute !important;
|
|
118
|
+
inset-block-start: $row-padding-medium !important;
|
|
119
|
+
inset-inline-start: $row-padding-medium !important;
|
|
120
|
+
width: $checkbox-size !important;
|
|
121
|
+
height: $checkbox-size !important;
|
|
122
|
+
margin: 0 !important;
|
|
123
|
+
padding: 0 !important;
|
|
124
|
+
clip: auto !important;
|
|
125
|
+
overflow: visible !important;
|
|
126
|
+
opacity: 0 !important;
|
|
127
|
+
cursor: inherit !important;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
&[data-size='large'] {
|
|
131
|
+
padding: $row-padding-large;
|
|
132
|
+
|
|
133
|
+
.hiddenInput {
|
|
134
|
+
inset-block-start: $row-padding-large !important;
|
|
135
|
+
inset-inline-start: $row-padding-large !important;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
124
138
|
}
|
|
125
139
|
|
|
126
140
|
.warning {
|
|
@@ -142,3 +156,71 @@ $transition-duration: 0.2s;
|
|
|
142
156
|
}
|
|
143
157
|
}
|
|
144
158
|
}
|
|
159
|
+
|
|
160
|
+
// Only rendered when `actions` is set, so the plain checkbox keeps its
|
|
161
|
+
// original single-element layout.
|
|
162
|
+
//
|
|
163
|
+
// The row reads as one unit, so the hover surface lives here rather than on
|
|
164
|
+
// `.root`. `.root` is the `<label>`, which ends with the label text — painting
|
|
165
|
+
// there leaves `actions` as a cold gap outside the highlight.
|
|
166
|
+
.wrapper {
|
|
167
|
+
display: inline-flex;
|
|
168
|
+
align-items: flex-start;
|
|
169
|
+
gap: var(--3xs);
|
|
170
|
+
border-radius: $checkbox-border-radius;
|
|
171
|
+
transition: background-color $transition-duration ease-in-out;
|
|
172
|
+
|
|
173
|
+
// Balances the root's inline padding on the far side of `actions`, so the
|
|
174
|
+
// highlight is not inset at one end and tight against the pin at the other.
|
|
175
|
+
padding-inline-end: $row-padding-medium;
|
|
176
|
+
|
|
177
|
+
&[data-size='large'] {
|
|
178
|
+
padding-inline-end: $row-padding-large;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
&:not([data-disabled]):hover,
|
|
182
|
+
&:not([data-disabled]):has(.root[data-focus-visible]) {
|
|
183
|
+
background-color: var(--background-secondary-hover);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
&[data-variant='warning']:not([data-disabled]):hover,
|
|
187
|
+
&[data-variant='warning']:not([data-disabled]):has(.root[data-focus-visible]) {
|
|
188
|
+
background-color: var(--background-warning);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
&:has(.root[data-focus-visible]) {
|
|
192
|
+
outline: $checkbox-focus-ring-width solid var(--background-primary-hover);
|
|
193
|
+
outline-offset: 0;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// The wrapper paints the row, so the label half must not paint a second,
|
|
197
|
+
// narrower highlight or ring inside it.
|
|
198
|
+
.root {
|
|
199
|
+
&:hover,
|
|
200
|
+
&[data-hover],
|
|
201
|
+
&[data-focus-visible] {
|
|
202
|
+
background-color: transparent;
|
|
203
|
+
outline: none;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Matches the height of the root's first row — the control plus the root's
|
|
209
|
+
// block padding — so the slot centres against the control at either size,
|
|
210
|
+
// with or without `labelInfo`.
|
|
211
|
+
//
|
|
212
|
+
// `margin-inline-start: auto` pins the slot to the end of the row whenever the
|
|
213
|
+
// row is wider than its content — a stretched list row, as inside a
|
|
214
|
+
// `DsCheckboxGroup` — matching Figma, where the pin sits at the row's trailing
|
|
215
|
+
// edge rather than hugging the label. It is inert when the row is content-width.
|
|
216
|
+
.actions {
|
|
217
|
+
display: inline-flex;
|
|
218
|
+
align-items: center;
|
|
219
|
+
flex-shrink: 0;
|
|
220
|
+
margin-inline-start: auto;
|
|
221
|
+
min-block-size: calc(#{$checkbox-size} + #{$row-padding-medium} * 2);
|
|
222
|
+
|
|
223
|
+
&[data-size='large'] {
|
|
224
|
+
min-block-size: calc(#{$checkbox-size} + #{$row-padding-large} * 2);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
@@ -15,19 +15,28 @@ import { DsIcon } from '../ds-icon';
|
|
|
15
15
|
*/
|
|
16
16
|
const DsCheckbox = ({
|
|
17
17
|
variant = 'default',
|
|
18
|
+
size = 'medium',
|
|
18
19
|
label,
|
|
19
20
|
labelInfo,
|
|
21
|
+
actions,
|
|
20
22
|
className,
|
|
23
|
+
style,
|
|
21
24
|
onCheckedChange,
|
|
22
25
|
value,
|
|
23
26
|
...props
|
|
24
27
|
}: DsCheckboxProps) => {
|
|
25
|
-
|
|
28
|
+
// `className` and `style` belong to whichever element is outermost, so they
|
|
29
|
+
// move to the wrapper when `actions` adds one.
|
|
30
|
+
const hasActions = Boolean(actions);
|
|
31
|
+
|
|
32
|
+
const checkbox = (
|
|
26
33
|
<Checkbox.Root
|
|
27
|
-
className={classNames(styles.root, variant === 'warning' && styles.warning, className)}
|
|
34
|
+
className={classNames(styles.root, variant === 'warning' && styles.warning, !hasActions && className)}
|
|
35
|
+
style={hasActions ? undefined : style}
|
|
28
36
|
onCheckedChange={(details) => onCheckedChange?.(details.checked)}
|
|
29
37
|
{...props}
|
|
30
38
|
value={value === undefined ? undefined : String(value)}
|
|
39
|
+
data-size={size}
|
|
31
40
|
>
|
|
32
41
|
<Checkbox.Control className={styles.control}>
|
|
33
42
|
<Checkbox.Indicator className={styles.indicator}>
|
|
@@ -46,6 +55,25 @@ const DsCheckbox = ({
|
|
|
46
55
|
)}
|
|
47
56
|
</Checkbox.Root>
|
|
48
57
|
);
|
|
58
|
+
|
|
59
|
+
if (!hasActions) {
|
|
60
|
+
return checkbox;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return (
|
|
64
|
+
<div
|
|
65
|
+
className={classNames(styles.wrapper, className)}
|
|
66
|
+
style={style}
|
|
67
|
+
data-size={size}
|
|
68
|
+
data-variant={variant}
|
|
69
|
+
data-disabled={props.disabled ? '' : undefined}
|
|
70
|
+
>
|
|
71
|
+
{checkbox}
|
|
72
|
+
<div className={styles.actions} data-size={size}>
|
|
73
|
+
{actions}
|
|
74
|
+
</div>
|
|
75
|
+
</div>
|
|
76
|
+
);
|
|
49
77
|
};
|
|
50
78
|
|
|
51
79
|
DsCheckbox.displayName = 'DsCheckbox';
|
|
@@ -4,6 +4,9 @@ import { type Checkbox } from '@ark-ui/react/checkbox';
|
|
|
4
4
|
export const checkboxVariants = ['default', 'warning'] as const;
|
|
5
5
|
export type CheckboxVariant = (typeof checkboxVariants)[number];
|
|
6
6
|
|
|
7
|
+
export const checkboxSizes = ['medium', 'large'] as const;
|
|
8
|
+
export type CheckboxSize = (typeof checkboxSizes)[number];
|
|
9
|
+
|
|
7
10
|
export interface DsCheckboxProps extends Omit<
|
|
8
11
|
ComponentPropsWithoutRef<typeof Checkbox.Root>,
|
|
9
12
|
'onCheckedChange' | 'value'
|
|
@@ -16,6 +19,7 @@ export interface DsCheckboxProps extends Omit<
|
|
|
16
19
|
* Visual variant of the checkbox
|
|
17
20
|
*/
|
|
18
21
|
variant?: CheckboxVariant;
|
|
22
|
+
size?: CheckboxSize;
|
|
19
23
|
/**
|
|
20
24
|
* Label for the checkbox
|
|
21
25
|
*/
|
|
@@ -24,6 +28,12 @@ export interface DsCheckboxProps extends Omit<
|
|
|
24
28
|
* Additional label info for the checkbox
|
|
25
29
|
*/
|
|
26
30
|
labelInfo?: ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* Trailing slot for interactive content, such as a pin or overflow menu.
|
|
33
|
+
* Rendered as a sibling of the checkbox rather than inside it: the checkbox
|
|
34
|
+
* root is a `<label>`,
|
|
35
|
+
*/
|
|
36
|
+
actions?: ReactNode;
|
|
27
37
|
/**
|
|
28
38
|
* Disables the checkbox, preventing user interaction
|
|
29
39
|
*/
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
@use '../../../styles/typography' as typography;
|
|
2
|
+
@use '../../../styles/shared/input' as input;
|
|
3
|
+
|
|
4
|
+
.container {
|
|
5
|
+
@include input.inputContainer;
|
|
6
|
+
gap: var(--xs);
|
|
7
|
+
|
|
8
|
+
&[data-invalid] {
|
|
9
|
+
--form-control-border-color: var(--background-error);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
&.small {
|
|
13
|
+
height: input.$input-text-height-small;
|
|
14
|
+
padding-block: var(--none);
|
|
15
|
+
|
|
16
|
+
.input,
|
|
17
|
+
.echo,
|
|
18
|
+
.input::placeholder {
|
|
19
|
+
line-height: calc(#{input.$input-text-height-small} - 2px);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&:hover:not([data-disabled]) {
|
|
24
|
+
border-color: var(--form-control-border-color, var(--background-action-hover));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:focus-within {
|
|
28
|
+
border-color: var(--form-control-border-color, var(--border-action-primary));
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.field {
|
|
33
|
+
position: relative;
|
|
34
|
+
display: flex;
|
|
35
|
+
flex: 1;
|
|
36
|
+
align-self: stretch;
|
|
37
|
+
min-width: 0;
|
|
38
|
+
cursor: text;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.editorSlot {
|
|
42
|
+
display: flex;
|
|
43
|
+
flex: 1;
|
|
44
|
+
align-self: stretch;
|
|
45
|
+
min-width: 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
.editorSlotHidden {
|
|
49
|
+
position: absolute;
|
|
50
|
+
width: 0;
|
|
51
|
+
height: 0;
|
|
52
|
+
overflow: hidden;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
.editorHost {
|
|
56
|
+
display: flex;
|
|
57
|
+
flex: 1;
|
|
58
|
+
align-self: stretch;
|
|
59
|
+
min-width: 0;
|
|
60
|
+
height: 100%;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.echo {
|
|
64
|
+
@include typography.code-sm-reg;
|
|
65
|
+
position: absolute;
|
|
66
|
+
inset: 0;
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: baseline;
|
|
69
|
+
overflow: hidden;
|
|
70
|
+
color: var(--font-main);
|
|
71
|
+
text-overflow: ellipsis;
|
|
72
|
+
white-space: nowrap;
|
|
73
|
+
pointer-events: none;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.placeholder {
|
|
77
|
+
color: var(--font-placeholder);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.input {
|
|
81
|
+
@include input.input;
|
|
82
|
+
@include typography.code-sm-reg;
|
|
83
|
+
width: 100%;
|
|
84
|
+
height: 100%;
|
|
85
|
+
padding: 0;
|
|
86
|
+
appearance: none;
|
|
87
|
+
transition: none;
|
|
88
|
+
white-space: pre;
|
|
89
|
+
overflow: hidden;
|
|
90
|
+
resize: none;
|
|
91
|
+
|
|
92
|
+
&:focus,
|
|
93
|
+
&:focus-visible {
|
|
94
|
+
outline: none;
|
|
95
|
+
box-shadow: none;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
&::placeholder {
|
|
99
|
+
@include typography.code-sm-reg;
|
|
100
|
+
color: var(--font-placeholder);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
&:disabled {
|
|
104
|
+
color: var(--font-disabled);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.container[data-disabled] .echo {
|
|
109
|
+
color: var(--font-disabled);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.fadeStart,
|
|
113
|
+
.fadeEnd {
|
|
114
|
+
position: absolute;
|
|
115
|
+
inset-block: 0;
|
|
116
|
+
width: var(--xl);
|
|
117
|
+
pointer-events: none;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.fadeStart {
|
|
121
|
+
inset-inline-start: 0;
|
|
122
|
+
background: linear-gradient(to right, var(--background), transparent);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.fadeEnd {
|
|
126
|
+
inset-inline-end: 0;
|
|
127
|
+
background: linear-gradient(to left, var(--background), transparent);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
.ellipsis {
|
|
131
|
+
position: absolute;
|
|
132
|
+
inset-block: 0;
|
|
133
|
+
inset-inline-end: 0;
|
|
134
|
+
display: flex;
|
|
135
|
+
align-items: center;
|
|
136
|
+
pointer-events: none;
|
|
137
|
+
color: var(--font-main);
|
|
138
|
+
background: var(--background);
|
|
139
|
+
|
|
140
|
+
&::after {
|
|
141
|
+
content: '…';
|
|
142
|
+
@include typography.code-sm-reg;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.indicator,
|
|
147
|
+
.indicatorButton {
|
|
148
|
+
@include typography.code-xs-reg;
|
|
149
|
+
flex: none;
|
|
150
|
+
color: var(--font-secondary);
|
|
151
|
+
white-space: nowrap;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.indicatorButton {
|
|
155
|
+
margin: 0;
|
|
156
|
+
padding: 0;
|
|
157
|
+
border: 0;
|
|
158
|
+
background: transparent;
|
|
159
|
+
cursor: pointer;
|
|
160
|
+
|
|
161
|
+
&:hover {
|
|
162
|
+
color: var(--font-main);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
&:focus-visible {
|
|
166
|
+
outline: 2px solid var(--border-action-primary);
|
|
167
|
+
outline-offset: 2px;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { type ReactNode, type Ref } from 'react';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import type { CodeInputSize } from '../ds-code-input.types';
|
|
4
|
+
import type { CollapsedIndicator } from '../use-collapsed-viewport';
|
|
5
|
+
import { DsStack } from '../../ds-stack';
|
|
6
|
+
import styles from './collapsed-code-field.module.scss';
|
|
7
|
+
|
|
8
|
+
export interface CollapsedCodeFieldProps {
|
|
9
|
+
size: CodeInputSize;
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
disabled: boolean;
|
|
12
|
+
invalid: boolean;
|
|
13
|
+
showEcho: boolean;
|
|
14
|
+
echoText: string;
|
|
15
|
+
fadeStart: boolean;
|
|
16
|
+
fadeEnd: boolean;
|
|
17
|
+
showEllipsis: boolean;
|
|
18
|
+
indicator: CollapsedIndicator | null;
|
|
19
|
+
additionalLinesLabel: (count: number) => string;
|
|
20
|
+
additionalLines: (count: number) => string;
|
|
21
|
+
linePosition: (current: number, total: number) => string;
|
|
22
|
+
selectionStatus: (selected: number, total: number) => string;
|
|
23
|
+
editorSlotRef: Ref<HTMLDivElement>;
|
|
24
|
+
adornment: ReactNode;
|
|
25
|
+
className?: string;
|
|
26
|
+
onExpand: () => void;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const CollapsedCodeField = ({
|
|
30
|
+
size,
|
|
31
|
+
placeholder,
|
|
32
|
+
disabled,
|
|
33
|
+
invalid,
|
|
34
|
+
showEcho,
|
|
35
|
+
echoText,
|
|
36
|
+
fadeStart,
|
|
37
|
+
fadeEnd,
|
|
38
|
+
showEllipsis,
|
|
39
|
+
indicator,
|
|
40
|
+
additionalLinesLabel,
|
|
41
|
+
additionalLines,
|
|
42
|
+
linePosition,
|
|
43
|
+
selectionStatus,
|
|
44
|
+
editorSlotRef,
|
|
45
|
+
adornment,
|
|
46
|
+
className,
|
|
47
|
+
onExpand,
|
|
48
|
+
}: CollapsedCodeFieldProps) => (
|
|
49
|
+
<div
|
|
50
|
+
className={classNames(styles.container, styles[size], className)}
|
|
51
|
+
data-disabled={disabled || undefined}
|
|
52
|
+
data-invalid={invalid || undefined}
|
|
53
|
+
>
|
|
54
|
+
<div className={styles.field}>
|
|
55
|
+
{/* While expanded, paint a fake line so the overlay can take the real
|
|
56
|
+
textarea without the compact row going empty. */}
|
|
57
|
+
{showEcho && (
|
|
58
|
+
<div className={classNames(styles.echo, !echoText && styles.placeholder)}>
|
|
59
|
+
{echoText || placeholder}
|
|
60
|
+
</div>
|
|
61
|
+
)}
|
|
62
|
+
<div
|
|
63
|
+
ref={editorSlotRef}
|
|
64
|
+
className={classNames(styles.editorSlot, showEcho && styles.editorSlotHidden)}
|
|
65
|
+
/>
|
|
66
|
+
{fadeStart && <div className={styles.fadeStart} aria-hidden />}
|
|
67
|
+
{fadeEnd && <div className={styles.fadeEnd} aria-hidden />}
|
|
68
|
+
{showEllipsis && !showEcho && <div className={styles.ellipsis} aria-hidden />}
|
|
69
|
+
</div>
|
|
70
|
+
<DsStack direction="row" alignItems="center" flex="none" gap="var(--xs)">
|
|
71
|
+
{indicator?.kind === 'plusN' && (
|
|
72
|
+
<button
|
|
73
|
+
type="button"
|
|
74
|
+
className={styles.indicatorButton}
|
|
75
|
+
aria-label={additionalLinesLabel(indicator.count)}
|
|
76
|
+
onClick={onExpand}
|
|
77
|
+
>
|
|
78
|
+
{additionalLines(indicator.count)}
|
|
79
|
+
</button>
|
|
80
|
+
)}
|
|
81
|
+
{indicator?.kind === 'line' && (
|
|
82
|
+
<span className={styles.indicator}>{linePosition(indicator.current, indicator.total)}</span>
|
|
83
|
+
)}
|
|
84
|
+
{indicator?.kind === 'selection' && (
|
|
85
|
+
<span className={styles.indicator}>{selectionStatus(indicator.selected, indicator.total)}</span>
|
|
86
|
+
)}
|
|
87
|
+
{adornment}
|
|
88
|
+
</DsStack>
|
|
89
|
+
</div>
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
export default CollapsedCodeField;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as CollapsedCodeField } from './collapsed-code-field';
|