@drivenets/design-system 0.16.0 → 0.18.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 +31 -0
- package/dist/index.cjs +1893 -824
- package/dist/index.d.cts +363 -247
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +363 -247
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1896 -829
- package/dist/index.js.map +1 -1
- package/dist/index.min.css +1 -1
- package/package.json +25 -25
- package/src/components/ds-alert-banner/ds-alert-banner-global.figma.ts +49 -0
- package/src/components/ds-alert-banner/ds-alert-banner.figma.ts +51 -0
- package/src/components/ds-alert-banner/ds-alert-banner.tsx +7 -6
- package/src/components/ds-autocomplete/ds-autocomplete.figma.ts +2 -2
- package/src/components/ds-autocomplete/ds-autocomplete.module.scss +15 -4
- package/src/components/ds-autocomplete/ds-autocomplete.tsx +10 -3
- package/src/components/ds-autocomplete/ds-autocomplete.types.ts +8 -0
- package/src/components/ds-avatar/ds-avatar.figma.ts +2 -2
- package/src/components/ds-avatar-group/ds-avatar-group.figma.ts +2 -2
- package/src/components/ds-breadcrumb/ds-breadcrumb.figma.ts +2 -2
- package/src/components/ds-button-v3/ds-button-v3.figma.ts +7 -5
- package/src/components/ds-button-v3/ds-button-v3.module.scss +84 -17
- package/src/components/ds-button-v3/ds-button-v3.tsx +2 -0
- package/src/components/ds-button-v3/ds-button-v3.types.ts +11 -2
- package/src/components/ds-button-v3/ds-button-v4.figma.ts +121 -0
- package/src/components/ds-card/figma/ds-card-content.figma.ts +2 -2
- package/src/components/ds-card/figma/ds-card-footer.figma.ts +2 -2
- package/src/components/ds-card/figma/ds-card-header.figma.ts +2 -2
- package/src/components/ds-card/figma/ds-card.figma.ts +2 -2
- package/src/components/ds-catalog-layout/ds-catalog-layout.figma.ts +51 -0
- package/src/components/ds-catalog-layout/ds-catalog-layout.tsx +9 -8
- package/src/components/ds-checkbox/ds-checkbox-level-2.figma.ts +2 -2
- package/src/components/ds-checkbox/ds-checkbox.figma.ts +2 -2
- package/src/components/ds-checkbox-group/ds-checkbox-group.figma.ts +2 -2
- package/src/components/ds-comment-bubble/ds-comment-bubble.figma.ts +52 -0
- package/src/components/ds-comment-card/ds-comment-card.figma.ts +36 -0
- package/src/components/ds-comment-indicator/ds-comment-indicator.figma.ts +32 -0
- package/src/components/ds-comments-drawer/components/comments-filter-modal/index.ts +0 -1
- package/src/components/ds-comments-drawer/ds-comments-drawer.figma.ts +19 -0
- package/src/components/ds-confirmation/ds-confirmation.tsx +13 -11
- package/src/components/ds-date-picker/ds-date-picker.figma.ts +2 -2
- package/src/components/ds-divider/ds-divider.figma.ts +2 -2
- package/src/components/ds-drawer/ds-drawer.tsx +11 -10
- package/src/components/ds-drawer/figma/ds-drawer-content.figma.ts +2 -2
- package/src/components/ds-drawer/figma/ds-drawer-footer.figma.ts +2 -2
- package/src/components/ds-drawer/figma/ds-drawer-header.figma.ts +2 -2
- package/src/components/ds-drawer/figma/ds-drawer.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-footer.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-group.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-item.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu-separator.figma.ts +2 -2
- package/src/components/ds-dropdown-menu/figma/ds-dropdown-menu.figma.ts +2 -2
- package/src/components/ds-expandable-text-input/ds-expandable-text-input.figma.ts +2 -2
- package/src/components/ds-file-upload/components/file-upload-item/index.ts +0 -1
- package/src/components/ds-file-upload/ds-file-upload.figma.ts +2 -2
- package/src/components/ds-filter-status-icon/ds-filter-status-icon.figma.ts +2 -2
- package/src/components/ds-form-control/ds-form-control.figma.ts +2 -2
- package/src/components/ds-form-control/ds-form-control.tsx +15 -13
- package/src/components/ds-icon/figma/ds-icon-material.figma.batch.ts +1 -1
- package/src/components/ds-icon/figma/ds-icon-special.figma.batch.ts +1 -1
- package/src/components/ds-key-value-pair/ds-key-value-pair.figma.ts +2 -2
- package/src/components/ds-loader/ds-loader.figma.ts +2 -2
- package/src/components/ds-modal/ds-modal.tsx +10 -9
- package/src/components/ds-modal/figma/ds-modal-content.figma.ts +2 -2
- package/src/components/ds-modal/figma/ds-modal-footer.figma.ts +2 -2
- package/src/components/ds-modal/figma/ds-modal-header.figma.ts +2 -2
- package/src/components/ds-modal/figma/ds-modal.figma.ts +2 -2
- package/src/components/ds-number-input/ds-number-input.tsx +1 -0
- package/src/components/ds-panel/ds-panel.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-content-item.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-content.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-footer.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover-header.figma.ts +2 -2
- package/src/components/ds-popover/figma/ds-popover.figma.ts +2 -2
- package/src/components/ds-progress-arc/ds-progress-arc.figma.ts +2 -2
- package/src/components/ds-progress-donut/ds-progress-donut.figma.ts +2 -2
- package/src/components/ds-progress-linear/ds-progress-linear.figma.ts +2 -2
- package/src/components/ds-progress-task-bar/ds-progress-task-bar.figma.ts +2 -2
- package/src/components/ds-radio-group/figma/ds-radio-group-item.figma.ts +2 -2
- package/src/components/ds-radio-group/figma/ds-radio-group.figma.ts +2 -2
- package/src/components/ds-segment-group/figma/ds-segment-group-item.figma.ts +2 -2
- package/src/components/ds-segment-group/figma/ds-segment-group.figma.ts +2 -2
- package/src/components/ds-select/ds-select.figma.ts +4 -3
- package/src/components/ds-select/ds-select.tsx +6 -1
- package/src/components/ds-select/ds-select.types.ts +2 -1
- package/src/components/ds-site-node/ds-site-node.figma.ts +2 -2
- package/src/components/ds-slider/ds-slider.figma.ts +29 -0
- package/src/components/ds-slider/ds-slider.module.scss +104 -0
- package/src/components/ds-slider/ds-slider.tsx +118 -0
- package/src/components/ds-slider/ds-slider.types.ts +102 -0
- package/src/components/ds-slider/ds-slider.utils.ts +14 -0
- package/src/components/ds-slider/index.ts +11 -0
- package/src/components/ds-smart-tabs/ds-smart-tabs.tsx +5 -4
- package/src/components/ds-smart-tabs/figma/ds-smart-tabs-tab.figma.ts +83 -0
- package/src/components/ds-smart-tabs/figma/ds-smart-tabs.figma.ts +23 -0
- package/src/components/ds-spinner/ds-spinner.figma.ts +2 -2
- package/src/components/ds-split-button/ds-split-button.figma.ts +2 -2
- package/src/components/ds-status-badge-v2/ds-status-badge-v2.figma.ts +2 -2
- package/src/components/ds-stepper/ds-stepper.figma.ts +2 -2
- package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.module.scss +5 -1
- package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.tsx +15 -3
- package/src/components/ds-table/components/ds-table-group-header-cell/index.ts +0 -1
- package/src/components/ds-table/components/ds-table-header/ds-table-header.module.scss +17 -3
- package/src/components/ds-table/components/ds-table-header/ds-table-header.tsx +30 -9
- package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.module.scss +23 -0
- package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.tsx +218 -0
- package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.types.ts +14 -0
- package/src/components/ds-table/components/ds-table-resize-handle/index.ts +1 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.module.scss +18 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.tsx +16 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/ds-table-resize-overlay.types.ts +13 -0
- package/src/components/ds-table/components/ds-table-resize-overlay/index.ts +1 -0
- package/src/components/ds-table/components/ds-table-row/ds-table-row.module.scss +1 -1
- package/src/components/ds-table/components/ds-table-row/ds-table-row.tsx +9 -2
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.module.scss +2 -1
- package/src/components/ds-table/components/ds-table-row-virtualized/ds-table-row-virtualized.tsx +9 -2
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-checkbox.tsx +2 -2
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-date.tsx +2 -1
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-number.tsx +2 -1
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-select.tsx +2 -1
- package/src/components/ds-table/components/edit/cell-editors/ds-table-edit-cell-text.tsx +2 -1
- package/src/components/ds-table/components/edit/ds-table-editing-cell/ds-table-editing-cell.tsx +12 -3
- package/src/components/ds-table/context/ds-table-context.tsx +208 -0
- package/src/components/ds-table/ds-table-defaults.ts +42 -0
- package/src/components/ds-table/ds-table.module.scss +19 -1
- package/src/components/ds-table/ds-table.tsx +163 -235
- package/src/components/ds-table/ds-table.types.ts +59 -47
- package/src/components/ds-table/figma/ds-table-expandable.figma.ts +2 -2
- package/src/components/ds-table/figma/ds-table.figma.ts +2 -2
- package/src/components/ds-table/grouping/utils/column-group.ts +7 -5
- package/src/components/ds-table/hooks/use-cell-editor.ts +5 -1
- package/src/components/ds-table/hooks/use-column-resize.ts +385 -0
- package/src/components/ds-table/hooks/use-editing-state.ts +190 -0
- package/src/components/ds-table/index.ts +1 -0
- package/src/components/ds-table/styles/_variables.scss +2 -1
- package/src/components/ds-table/utils/column-size-meta.augmentation.ts +16 -0
- package/src/components/ds-table/utils/column-size.ts +213 -10
- package/src/components/ds-table/utils/column-size.unit.test.ts +213 -0
- package/src/components/ds-table/utils/constants.ts +28 -0
- package/src/components/ds-table/utils/frozen-body.ts +33 -0
- package/src/components/ds-table/utils/frozen-body.unit.test.ts +44 -0
- package/src/components/ds-table/utils/table-api.ts +42 -0
- package/src/components/ds-table/utils/table-api.unit.test.ts +82 -0
- package/src/components/ds-table/utils/table-columns.tsx +119 -0
- package/src/components/ds-table/utils/table-columns.unit.test.ts +199 -0
- package/src/components/ds-tabs/figma/ds-tabs-tab-vertical.figma.ts +2 -2
- package/src/components/ds-tabs/figma/ds-tabs-tab.figma.ts +2 -2
- package/src/components/ds-tabs/figma/ds-tabs-vertical.figma.ts +2 -2
- package/src/components/ds-tabs/figma/ds-tabs.figma.ts +2 -2
- package/src/components/ds-tag/ds-tag.figma.ts +51 -0
- package/src/components/ds-tag-filter/ds-tag-filter.figma.ts +16 -0
- package/src/components/ds-text-input/ds-input-field-v02.figma.ts +31 -6
- package/src/components/ds-text-input/ds-text-input.figma.ts +5 -4
- package/src/components/ds-text-input/ds-text-input.tsx +1 -0
- package/src/components/ds-text-input/ds-text-input.types.ts +1 -1
- package/src/components/ds-time-picker/ds-time-picker.figma.ts +2 -2
- package/src/components/ds-toast/ds-toast.figma.ts +3 -3
- package/src/components/ds-toggle/ds-toggle.figma.ts +2 -2
- package/src/components/ds-tooltip/ds-tooltip.figma.ts +2 -2
- package/src/components/ds-tree/ds-tree.figma.ts +54 -0
- package/src/components/ds-tree/ds-tree.module.scss +2 -2
- package/src/components/ds-tree/ds-tree.tsx +6 -0
- package/src/components/ds-tree/ds-tree.types.ts +16 -0
- package/src/components/ds-typography/ds-typography.figma.ts +2 -2
- package/src/components/ds-user-card/ds-user-card.figma.ts +2 -2
- package/src/components/ds-vertical-tabs/ds-vertical-tabs.tsx +13 -6
- package/src/components/ds-workspace-layout/ds-workspace-layout.figma.ts +99 -0
- package/src/components/ds-workspace-layout/ds-workspace-layout.module.scss +1 -8
- package/src/components/ds-workspace-layout/ds-workspace-layout.tsx +11 -10
- package/src/index.ts +1 -0
- package/src/styles/_gradients.scss +19 -0
- package/src/styles/_root.scss +39 -15
- package/src/styles/_typography.scss +1 -0
- package/src/styles/shared/_input.scss +10 -0
- package/src/styles/styles.scss +1 -0
- package/src/components/ds-table/context/ds-table-context.ts +0 -112
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { Slider, type SliderValueChangeDetails } from '@ark-ui/react/slider';
|
|
2
|
+
import classNames from 'classnames';
|
|
3
|
+
import { useControlled } from '../../utils/use-controlled';
|
|
4
|
+
import { DsTypography } from '../ds-typography';
|
|
5
|
+
import type { DsSliderProps, DsSliderValue } from './ds-slider.types';
|
|
6
|
+
import { toArray } from './ds-slider.utils';
|
|
7
|
+
import styles from './ds-slider.module.scss';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @summary Selects a numeric value or a numeric interval by dragging thumbs along a track.
|
|
11
|
+
*
|
|
12
|
+
* Use for picking a number or interval from a known continuous range where visual
|
|
13
|
+
* adjustment beats typing (filter ranges, thresholds, capacity limits). For exact
|
|
14
|
+
* numeric entry use DsNumberInput; for a few discrete options use DsSegmentGroup.
|
|
15
|
+
*/
|
|
16
|
+
const DsSlider = ({
|
|
17
|
+
ref,
|
|
18
|
+
className,
|
|
19
|
+
style,
|
|
20
|
+
label,
|
|
21
|
+
type = 'value',
|
|
22
|
+
size = 'medium',
|
|
23
|
+
min = 0,
|
|
24
|
+
max = 100,
|
|
25
|
+
step = 1,
|
|
26
|
+
value,
|
|
27
|
+
defaultValue,
|
|
28
|
+
name,
|
|
29
|
+
disabled = false,
|
|
30
|
+
thumbLabels,
|
|
31
|
+
formatValue = String,
|
|
32
|
+
onValueChange,
|
|
33
|
+
onValueChangeEnd,
|
|
34
|
+
}: DsSliderProps) => {
|
|
35
|
+
const isRange = type === 'range';
|
|
36
|
+
|
|
37
|
+
const controlledValue = toArray(value);
|
|
38
|
+
const fallbackValue = isRange ? [min, max] : [min];
|
|
39
|
+
|
|
40
|
+
const toPublicValue = (next: number[]): DsSliderValue =>
|
|
41
|
+
isRange ? [next[0] ?? min, next[1] ?? max] : (next[0] ?? min);
|
|
42
|
+
|
|
43
|
+
const [values, setValues] = useControlled<number[]>(
|
|
44
|
+
controlledValue,
|
|
45
|
+
controlledValue !== undefined ? (next) => onValueChange?.(toPublicValue(next)) : undefined,
|
|
46
|
+
toArray(defaultValue) ?? fallbackValue,
|
|
47
|
+
);
|
|
48
|
+
|
|
49
|
+
const handleValueChange = (details: SliderValueChangeDetails) => {
|
|
50
|
+
setValues(details.value);
|
|
51
|
+
|
|
52
|
+
if (controlledValue === undefined) {
|
|
53
|
+
onValueChange?.(toPublicValue(details.value));
|
|
54
|
+
}
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const valueText = isRange
|
|
58
|
+
? `${formatValue(values[0] ?? min)}-${formatValue(values[1] ?? max)}`
|
|
59
|
+
: formatValue(values[0] ?? min);
|
|
60
|
+
|
|
61
|
+
const textColor = disabled ? 'disabled' : 'main';
|
|
62
|
+
|
|
63
|
+
const thumbAriaLabels = isRange ? thumbLabels : label ? [label] : thumbLabels;
|
|
64
|
+
|
|
65
|
+
const rootClass = classNames(
|
|
66
|
+
styles.root,
|
|
67
|
+
{
|
|
68
|
+
[styles.small]: size === 'small',
|
|
69
|
+
[styles.large]: size === 'large',
|
|
70
|
+
},
|
|
71
|
+
className,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<Slider.Root
|
|
76
|
+
ref={ref}
|
|
77
|
+
className={rootClass}
|
|
78
|
+
style={style}
|
|
79
|
+
value={values}
|
|
80
|
+
min={min}
|
|
81
|
+
max={max}
|
|
82
|
+
step={step}
|
|
83
|
+
name={name}
|
|
84
|
+
disabled={disabled}
|
|
85
|
+
aria-label={thumbAriaLabels}
|
|
86
|
+
onValueChange={handleValueChange}
|
|
87
|
+
onValueChangeEnd={(details) => onValueChangeEnd?.(toPublicValue(details.value))}
|
|
88
|
+
>
|
|
89
|
+
<div className={styles.header}>
|
|
90
|
+
{label && (
|
|
91
|
+
<DsTypography variant="body-sm-md" color={textColor}>
|
|
92
|
+
{label}
|
|
93
|
+
</DsTypography>
|
|
94
|
+
)}
|
|
95
|
+
|
|
96
|
+
<DsTypography variant="body-sm-md" color={textColor} className={styles.valueText}>
|
|
97
|
+
{valueText}
|
|
98
|
+
</DsTypography>
|
|
99
|
+
</div>
|
|
100
|
+
|
|
101
|
+
<Slider.Control className={styles.control}>
|
|
102
|
+
<Slider.Track className={styles.track}>
|
|
103
|
+
<Slider.Range className={styles.range} />
|
|
104
|
+
</Slider.Track>
|
|
105
|
+
|
|
106
|
+
{values.map((_, index) => (
|
|
107
|
+
<Slider.Thumb key={index} index={index} className={styles.thumb}>
|
|
108
|
+
<Slider.HiddenInput />
|
|
109
|
+
</Slider.Thumb>
|
|
110
|
+
))}
|
|
111
|
+
</Slider.Control>
|
|
112
|
+
</Slider.Root>
|
|
113
|
+
);
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
DsSlider.displayName = 'DsSlider';
|
|
117
|
+
|
|
118
|
+
export default DsSlider;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { CSSProperties, Ref } from 'react';
|
|
2
|
+
|
|
3
|
+
export const sliderTypes = ['value', 'range'] as const;
|
|
4
|
+
export type DsSliderType = (typeof sliderTypes)[number];
|
|
5
|
+
|
|
6
|
+
export const sliderSizes = ['small', 'medium', 'large'] as const;
|
|
7
|
+
export type DsSliderSize = (typeof sliderSizes)[number];
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Value for a `value` slider (single number) or a `range` slider ([min, max] tuple).
|
|
11
|
+
*/
|
|
12
|
+
export type DsSliderValue = number | [number, number];
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Props for the DsSlider component.
|
|
16
|
+
*/
|
|
17
|
+
export type DsSliderProps = {
|
|
18
|
+
/**
|
|
19
|
+
* Forwarded ref for the slider root element.
|
|
20
|
+
*/
|
|
21
|
+
ref?: Ref<HTMLDivElement>;
|
|
22
|
+
|
|
23
|
+
className?: string;
|
|
24
|
+
|
|
25
|
+
style?: CSSProperties;
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Visible label rendered above the track. Becomes the accessible name of the control.
|
|
29
|
+
*/
|
|
30
|
+
label?: string;
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Selection mode: a single value or a `[min, max]` interval.
|
|
34
|
+
* @default 'value'
|
|
35
|
+
*/
|
|
36
|
+
type?: DsSliderType;
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Drives thumb and track sizing together (S/M/L → 16/20/24px thumb, 2/4/8px track).
|
|
40
|
+
* Accepts a responsive value (e.g. `{ md: 'small', lg: 'medium' }`).
|
|
41
|
+
* @default 'medium'
|
|
42
|
+
*/
|
|
43
|
+
size?: DsSliderSize;
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Lowest selectable value.
|
|
47
|
+
* @default 0
|
|
48
|
+
*/
|
|
49
|
+
min?: number;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Highest selectable value.
|
|
53
|
+
* @default 100
|
|
54
|
+
*/
|
|
55
|
+
max?: number;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Granularity that the value snaps to. Must be greater than 0.
|
|
59
|
+
* Accepts a responsive value (e.g. `{ md: 5, lg: 1 }`).
|
|
60
|
+
* @default 1
|
|
61
|
+
*/
|
|
62
|
+
step?: number;
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* Controlled value. A number for `type="value"`, a `[min, max]` tuple for `type="range"`.
|
|
66
|
+
*/
|
|
67
|
+
value?: DsSliderValue;
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Uncontrolled initial value. Defaults to `min` for `value` and `[min, max]` for `range`.
|
|
71
|
+
*/
|
|
72
|
+
defaultValue?: DsSliderValue;
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Form field name applied to the hidden inputs.
|
|
76
|
+
*/
|
|
77
|
+
name?: string;
|
|
78
|
+
|
|
79
|
+
disabled?: boolean;
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Accessible name per thumb. Required for `type="range"` (e.g. `['Minimum', 'Maximum']`).
|
|
83
|
+
* Accepts a responsive value (e.g. `{ md: ['Min', 'Max'], lg: ['Minimum', 'Maximum'] }`).
|
|
84
|
+
*/
|
|
85
|
+
thumbLabels?: string[];
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Formats each number shown in the output above the track. Range values are joined with `-`.
|
|
89
|
+
* @default String
|
|
90
|
+
*/
|
|
91
|
+
formatValue?: (value: number) => string;
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Called live while the value changes (drag or keyboard).
|
|
95
|
+
*/
|
|
96
|
+
onValueChange?: (value: DsSliderValue) => void;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Called once an interaction settles (pointer released or key committed).
|
|
100
|
+
*/
|
|
101
|
+
onValueChangeEnd?: (value: DsSliderValue) => void;
|
|
102
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DsSliderValue } from './ds-slider.types';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Normalizes the public value (a number or a `[min, max]` tuple) into the
|
|
5
|
+
* `number[]` shape Ark's slider works with. Returns `undefined` when no value
|
|
6
|
+
* is provided so controlled/uncontrolled detection stays intact.
|
|
7
|
+
*/
|
|
8
|
+
export const toArray = (value: DsSliderValue | undefined): number[] | undefined => {
|
|
9
|
+
if (value === undefined) {
|
|
10
|
+
return undefined;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
return Array.isArray(value) ? value : [value];
|
|
14
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ComponentProps } from 'react';
|
|
2
|
+
|
|
3
|
+
import { withResponsiveProps } from '../../utils/responsive';
|
|
4
|
+
import DsSliderBase from './ds-slider';
|
|
5
|
+
|
|
6
|
+
export const DsSlider = withResponsiveProps(DsSliderBase, ['size', 'step', 'thumbLabels']);
|
|
7
|
+
|
|
8
|
+
DsSlider.displayName = 'DsSlider';
|
|
9
|
+
|
|
10
|
+
export type DsSliderProps = ComponentProps<typeof DsSlider>;
|
|
11
|
+
export type { DsSliderValue, DsSliderType, DsSliderSize } from './ds-slider.types';
|
|
@@ -86,7 +86,7 @@ const DsSmartTab: React.FC<DsSmartTabProps> = ({
|
|
|
86
86
|
/**
|
|
87
87
|
* Design system SmartTabs component
|
|
88
88
|
*/
|
|
89
|
-
const
|
|
89
|
+
const DsSmartTabsRoot = ({
|
|
90
90
|
activeTab,
|
|
91
91
|
onTabClick,
|
|
92
92
|
className,
|
|
@@ -110,8 +110,9 @@ const DsSmartTabs = ({
|
|
|
110
110
|
|
|
111
111
|
DsSmartTab.displayName = 'DsSmartTabs.Tab';
|
|
112
112
|
|
|
113
|
-
DsSmartTabs
|
|
114
|
-
|
|
115
|
-
|
|
113
|
+
const DsSmartTabs = Object.assign(DsSmartTabsRoot, {
|
|
114
|
+
displayName: 'DsSmartTabs',
|
|
115
|
+
Tab: DsSmartTab,
|
|
116
|
+
});
|
|
116
117
|
|
|
117
118
|
export default DsSmartTabs;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
// url=https://www.figma.com/design/nha3m67y7S57cHCSuQO2gp/DAP-Design-System-1.2?node-id=15707-16204
|
|
2
|
+
// source=https://github.com/drivenets/design-system/tree/main/packages/design-system/src/components/ds-smart-tabs
|
|
3
|
+
// component=DsSmartTabs.Tab
|
|
4
|
+
//
|
|
5
|
+
// `Part_SmartTabV1` maps to `DsSmartTabs.Tab`, resolved inside the group's
|
|
6
|
+
// `Smart tabs slot` (nestable). Each item = colored icon badge + label + count.
|
|
7
|
+
//
|
|
8
|
+
// Variant divergence — the Figma `state` axis (selected/unselected/hover/focus)
|
|
9
|
+
// is mostly visual: selection is owned by `DsSmartTabs` (`activeTab`), and
|
|
10
|
+
// hover/focus are driven by CSS. Only `disabled` maps to a `DsSmartTabs.Tab` prop.
|
|
11
|
+
//
|
|
12
|
+
// `color` is intentionally not emitted: it is a fixed semantic per-category value
|
|
13
|
+
// (encoded in the nested badge's `category` variant, not a tab-level property) and
|
|
14
|
+
// the category→color mapping is owned by the design system, so the developer sets
|
|
15
|
+
// it explicitly. `value` is data, not derivable from Figma, so slugify the label
|
|
16
|
+
// as a sensible default for the developer to confirm/replace.
|
|
17
|
+
import figma from 'figma';
|
|
18
|
+
|
|
19
|
+
const instance = figma.selectedInstance;
|
|
20
|
+
|
|
21
|
+
const state = instance.getEnum('state', {
|
|
22
|
+
selected: 'selected',
|
|
23
|
+
unselected: 'unselected',
|
|
24
|
+
hover: 'hover',
|
|
25
|
+
focus: 'focus',
|
|
26
|
+
disabled: 'disabled',
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Label and count are plain text layers (not component properties): the first
|
|
30
|
+
// text child is the label, the second is the right-aligned count.
|
|
31
|
+
const texts = instance.children.filter((child): child is figma.TextHandle => child.type === 'TEXT');
|
|
32
|
+
const label = texts[0]?.textContent.trim() || 'Label';
|
|
33
|
+
const count = texts[1]?.textContent.trim() ?? '';
|
|
34
|
+
|
|
35
|
+
const value = label
|
|
36
|
+
.toLowerCase()
|
|
37
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
38
|
+
.replace(/^-+|-+$/g, '');
|
|
39
|
+
|
|
40
|
+
// The badge glyph maps to `DsSmartTabs.Tab.icon` (an icon-name string). Prefer a
|
|
41
|
+
// connected ds-icon's Code Connect id and fall back to the glyph layer name.
|
|
42
|
+
const resolveIcon = (): string => {
|
|
43
|
+
const node = instance
|
|
44
|
+
.findConnectedInstances((n) => n.codeConnectId()?.startsWith('ds-icon-') ?? false, {
|
|
45
|
+
traverseInstances: true,
|
|
46
|
+
})
|
|
47
|
+
.find((n): n is figma.InstanceHandle => n.type === 'INSTANCE');
|
|
48
|
+
|
|
49
|
+
const id = node?.codeConnectId();
|
|
50
|
+
if (id?.startsWith('ds-icon-o-')) {
|
|
51
|
+
return id.slice('ds-icon-o-'.length);
|
|
52
|
+
}
|
|
53
|
+
if (id?.startsWith('ds-icon-s-')) {
|
|
54
|
+
return id.slice('ds-icon-s-'.length);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
return (node?.name ?? 'circle')
|
|
58
|
+
.replace(/^DAP_GM_[OS]_/, '')
|
|
59
|
+
.replace(/^DAP_/, '')
|
|
60
|
+
.replace(/[\s/]+/g, '_')
|
|
61
|
+
.toLowerCase();
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// `content` is number|string and is not auto-formatted: emit a numeric literal for
|
|
65
|
+
// a plain integer, otherwise keep the pre-formatted string (e.g. "1,273").
|
|
66
|
+
const contentAttr = /^\d+$/.test(count) ? `content={${count}}` : `content="${count}"`;
|
|
67
|
+
|
|
68
|
+
const attrs = [
|
|
69
|
+
`value="${value}"`,
|
|
70
|
+
`label="${label}"`,
|
|
71
|
+
`icon="${resolveIcon()}"`,
|
|
72
|
+
contentAttr,
|
|
73
|
+
state === 'disabled' ? 'disabled' : '',
|
|
74
|
+
]
|
|
75
|
+
.filter(Boolean)
|
|
76
|
+
.join(' ');
|
|
77
|
+
|
|
78
|
+
export default {
|
|
79
|
+
example: figma.code`<DsSmartTabs.Tab ${attrs} />`,
|
|
80
|
+
imports: ["import { DsSmartTabs } from '@drivenets/design-system';"],
|
|
81
|
+
id: 'ds-smart-tabs-tab',
|
|
82
|
+
metadata: { nestable: true },
|
|
83
|
+
} satisfies figma.Template;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
// url=https://www.figma.com/design/nha3m67y7S57cHCSuQO2gp/DAP-Design-System-1.2?node-id=34864-129238
|
|
2
|
+
// source=https://github.com/drivenets/design-system/tree/main/packages/design-system/src/components/ds-smart-tabs
|
|
3
|
+
// component=DsSmartTabs
|
|
4
|
+
//
|
|
5
|
+
// `DsSmartTabsV1` is the smart-tabs filter row. It maps to `DsSmartTabs`, whose
|
|
6
|
+
// `Smart tabs slot` resolves each item via its own template (`DsSmartTabs.Tab`),
|
|
7
|
+
// so added/removed tabs stay in sync.
|
|
8
|
+
//
|
|
9
|
+
// `activeTab` and `onTabClick` are the controlled selection pair. Figma models
|
|
10
|
+
// only the row chrome — selection state is authored in code, so the snippet emits
|
|
11
|
+
// identifier placeholders for the developer to wire to component state.
|
|
12
|
+
import figma from 'figma';
|
|
13
|
+
|
|
14
|
+
const tabs = figma.selectedInstance.getSlot('Smart tabs slot');
|
|
15
|
+
|
|
16
|
+
export default {
|
|
17
|
+
example: figma.code`<DsSmartTabs activeTab={activeTab} onTabClick={setActiveTab}>
|
|
18
|
+
${tabs}
|
|
19
|
+
</DsSmartTabs>`,
|
|
20
|
+
imports: ["import { DsSmartTabs } from '@drivenets/design-system';"],
|
|
21
|
+
id: 'ds-smart-tabs',
|
|
22
|
+
metadata: { nestable: false },
|
|
23
|
+
} satisfies figma.Template;
|
|
@@ -13,7 +13,7 @@ const size = instance.getEnum('Size', {
|
|
|
13
13
|
|
|
14
14
|
export default {
|
|
15
15
|
example: figma.code`<DsSpinner size="${size}" />`,
|
|
16
|
-
imports: ["import { DsSpinner } from '@drivenets/design-system'"],
|
|
16
|
+
imports: ["import { DsSpinner } from '@drivenets/design-system';"],
|
|
17
17
|
id: 'ds-spinner',
|
|
18
18
|
metadata: { nestable: true },
|
|
19
|
-
};
|
|
19
|
+
} satisfies figma.Template;
|
|
@@ -89,7 +89,7 @@ const buttonProps = [
|
|
|
89
89
|
|
|
90
90
|
export default {
|
|
91
91
|
example: figma.code`<DsSplitButton size="${size}"${disabled ? ' disabled' : ''} slotProps={{ button: { ${buttonProps} }, select: { options: [], value: '' } }} />`,
|
|
92
|
-
imports: ["import { DsSplitButton } from '@drivenets/design-system'"],
|
|
92
|
+
imports: ["import { DsSplitButton } from '@drivenets/design-system';"],
|
|
93
93
|
id: 'ds-split-button',
|
|
94
94
|
metadata: { nestable: false },
|
|
95
|
-
};
|
|
95
|
+
} satisfies figma.Template;
|
|
@@ -35,7 +35,7 @@ export default {
|
|
|
35
35
|
: structure === 'text-only'
|
|
36
36
|
? figma.code`<DsStatusBadgeV2 phase="${phase}" label="${label}" variant="${variant}" size="${size}" icon={null} />`
|
|
37
37
|
: figma.code`<DsStatusBadgeV2 phase="${phase}" label="${label}" variant="${variant}" size="${size}" />`,
|
|
38
|
-
imports: ["import { DsStatusBadgeV2 } from '@drivenets/design-system'"],
|
|
38
|
+
imports: ["import { DsStatusBadgeV2 } from '@drivenets/design-system';"],
|
|
39
39
|
id: 'ds-status-badge-v2',
|
|
40
40
|
metadata: { nestable: true },
|
|
41
|
-
};
|
|
41
|
+
} satisfies figma.Template;
|
|
@@ -32,7 +32,7 @@ export default {
|
|
|
32
32
|
</DsStep>
|
|
33
33
|
{/* Add a <DsStep> per step */}
|
|
34
34
|
</DsStepper>`,
|
|
35
|
-
imports: ["import { DsStepper, DsStep, DsStepContent, DsNextStepButton } from '@drivenets/design-system'"],
|
|
35
|
+
imports: ["import { DsStepper, DsStep, DsStepContent, DsNextStepButton } from '@drivenets/design-system';"],
|
|
36
36
|
id: 'ds-stepper',
|
|
37
37
|
metadata: { nestable: true },
|
|
38
|
-
};
|
|
38
|
+
} satisfies figma.Template;
|
|
@@ -3,11 +3,15 @@
|
|
|
3
3
|
|
|
4
4
|
.groupHeaderCell {
|
|
5
5
|
@include typography.body-sm-md;
|
|
6
|
+
position: relative;
|
|
6
7
|
color: var(--font-main);
|
|
7
8
|
height: var(--ds-table-header-height);
|
|
8
9
|
padding: 0;
|
|
9
10
|
border-bottom: vars.$border-width solid var(--color-dap-gray-400);
|
|
10
|
-
|
|
11
|
+
|
|
12
|
+
&:not(:first-child) {
|
|
13
|
+
border-left: vars.$group-border-width solid var(--border);
|
|
14
|
+
}
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
.groupHeaderContent {
|
package/src/components/ds-table/components/ds-table-group-header-cell/ds-table-group-header-cell.tsx
CHANGED
|
@@ -3,21 +3,27 @@ import { DsButtonV3 } from '../../../ds-button-v3';
|
|
|
3
3
|
import { TableHead } from '../core-table';
|
|
4
4
|
import { useDsTableContext } from '../../context/ds-table-context';
|
|
5
5
|
import { getGroupColumnSizeStyle } from '../../grouping';
|
|
6
|
+
import { getResizableHeaderStyle } from '../../utils/column-size';
|
|
6
7
|
import { defaultDsTableLocale } from '../../ds-table.types';
|
|
8
|
+
import { DsTableResizeHandle } from '../ds-table-resize-handle';
|
|
7
9
|
import type { DsTableGroupHeaderCellProps } from './ds-table-group-header-cell.types';
|
|
8
10
|
import styles from './ds-table-group-header-cell.module.scss';
|
|
9
11
|
|
|
10
12
|
export const DsTableGroupHeaderCell = <TData, TValue>({
|
|
11
13
|
header,
|
|
12
14
|
}: DsTableGroupHeaderCellProps<TData, TValue>) => {
|
|
13
|
-
const { collapsedColumnGroups, onToggleColumnGroup, locale } =
|
|
15
|
+
const { collapsedColumnGroups, onToggleColumnGroup, locale, resizableColumns, resizeSizingReady } =
|
|
16
|
+
useDsTableContext<TData, TValue>();
|
|
14
17
|
|
|
15
18
|
const groupId = header.column.id;
|
|
16
19
|
const visibleLeafColumns = header.column.getLeafColumns().filter((leaf) => leaf.getIsVisible());
|
|
17
|
-
const groupStyle =
|
|
20
|
+
const groupStyle = resizeSizingReady
|
|
21
|
+
? getResizableHeaderStyle(header.id)
|
|
22
|
+
: getGroupColumnSizeStyle(visibleLeafColumns, {});
|
|
18
23
|
|
|
19
24
|
const isCollapsible = header.column.columnDef.meta?.group?.collapsible ?? false;
|
|
20
25
|
const isCollapsed = collapsedColumnGroups?.includes(groupId) ?? false;
|
|
26
|
+
const canResize = resizableColumns && !isCollapsed && header.column.getCanResize();
|
|
21
27
|
|
|
22
28
|
const mergedLocale = { ...defaultDsTableLocale, ...locale };
|
|
23
29
|
const toggleLabel = isCollapsed ? mergedLocale.expandColumnGroup : mergedLocale.collapseColumnGroup;
|
|
@@ -25,7 +31,12 @@ export const DsTableGroupHeaderCell = <TData, TValue>({
|
|
|
25
31
|
const handleToggle = () => onToggleColumnGroup?.(groupId);
|
|
26
32
|
|
|
27
33
|
return (
|
|
28
|
-
<TableHead
|
|
34
|
+
<TableHead
|
|
35
|
+
data-column-id={groupId}
|
|
36
|
+
className={styles.groupHeaderCell}
|
|
37
|
+
style={groupStyle}
|
|
38
|
+
colSpan={header.colSpan}
|
|
39
|
+
>
|
|
29
40
|
<div className={styles.groupHeaderContent}>
|
|
30
41
|
<span className={styles.groupLabel}>
|
|
31
42
|
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
@@ -43,6 +54,7 @@ export const DsTableGroupHeaderCell = <TData, TValue>({
|
|
|
43
54
|
/>
|
|
44
55
|
)}
|
|
45
56
|
</div>
|
|
57
|
+
{canResize && <DsTableResizeHandle header={header} />}
|
|
46
58
|
</TableHead>
|
|
47
59
|
);
|
|
48
60
|
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
@use '../../../../styles/typography';
|
|
2
2
|
@use '../../styles/variables' as vars;
|
|
3
3
|
|
|
4
|
-
.
|
|
5
|
-
background-color: var(--background);
|
|
4
|
+
.header {
|
|
5
|
+
background-color: var(--background-secondary);
|
|
6
|
+
overflow: hidden;
|
|
6
7
|
}
|
|
7
8
|
|
|
8
9
|
.virtualizedHeader {
|
|
@@ -28,6 +29,7 @@
|
|
|
28
29
|
|
|
29
30
|
.headerCell {
|
|
30
31
|
@include typography.body-sm-md;
|
|
32
|
+
position: relative;
|
|
31
33
|
color: var(--font-main);
|
|
32
34
|
text-align: left;
|
|
33
35
|
padding: 0 var(--standard);
|
|
@@ -57,7 +59,7 @@
|
|
|
57
59
|
justify-content: center;
|
|
58
60
|
}
|
|
59
61
|
|
|
60
|
-
.groupStart {
|
|
62
|
+
.groupStart:not(:first-child) {
|
|
61
63
|
border-left: vars.$group-border-width solid var(--border);
|
|
62
64
|
}
|
|
63
65
|
|
|
@@ -69,6 +71,18 @@
|
|
|
69
71
|
height: 100%;
|
|
70
72
|
}
|
|
71
73
|
|
|
74
|
+
.headerLabelStack {
|
|
75
|
+
min-width: 0;
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.headerLabel {
|
|
80
|
+
display: block;
|
|
81
|
+
overflow: hidden;
|
|
82
|
+
text-overflow: ellipsis;
|
|
83
|
+
white-space: nowrap;
|
|
84
|
+
}
|
|
85
|
+
|
|
72
86
|
.filterTriggerContainer {
|
|
73
87
|
display: inline-flex;
|
|
74
88
|
align-items: center;
|
|
@@ -6,21 +6,20 @@ import styles from './ds-table-header.module.scss';
|
|
|
6
6
|
import stylesShared from '../../styles/shared/ds-table-shared.module.scss';
|
|
7
7
|
import type { DsTableHeaderProps } from './ds-table-header.types';
|
|
8
8
|
import { useDsTableContext } from '../../context/ds-table-context';
|
|
9
|
-
import {
|
|
9
|
+
import { getHeaderCellSizeStyle, isExplicitColumnWidth } from '../../utils/column-size';
|
|
10
10
|
import { SELECT_COLUMN_ID } from '../../utils/constants';
|
|
11
11
|
import { DsStack } from '../../../ds-stack';
|
|
12
12
|
import { DsTableColumnFilterPopover } from '../../filters/components/column-filter-popover';
|
|
13
13
|
import type { ResolvedColumnFilter } from '../../filters/types/filter-adapter.types';
|
|
14
14
|
import { DsTableGroupHeaderCell } from '../ds-table-group-header-cell';
|
|
15
|
+
import { DsTableResizeHandle } from '../ds-table-resize-handle';
|
|
15
16
|
import { isFirstLeafColumnOfGroup } from '../../grouping';
|
|
16
17
|
|
|
17
18
|
const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
18
|
-
const {
|
|
19
|
+
const { bordered, virtualized, resizableColumns, resizeSizingReady } = useDsTableContext<TData, unknown>();
|
|
19
20
|
|
|
20
21
|
return (
|
|
21
|
-
<TableHeader
|
|
22
|
-
className={classnames(stickyHeader && styles.stickyHeader, virtualized && styles.virtualizedHeader)}
|
|
23
|
-
>
|
|
22
|
+
<TableHeader className={classnames(styles.header, virtualized && styles.virtualizedHeader)}>
|
|
24
23
|
{table.getHeaderGroups().map((headerGroup) => (
|
|
25
24
|
<TableRow
|
|
26
25
|
key={headerGroup.id}
|
|
@@ -31,12 +30,19 @@ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
|
31
30
|
)}
|
|
32
31
|
>
|
|
33
32
|
{headerGroup.headers.map((header) => {
|
|
33
|
+
const columnSizing = table.getState().columnSizing;
|
|
34
|
+
|
|
34
35
|
if (header.isPlaceholder) {
|
|
35
36
|
return (
|
|
36
37
|
<TableHead
|
|
37
38
|
key={header.id}
|
|
38
39
|
className={styles.headerCell}
|
|
39
|
-
style={
|
|
40
|
+
style={getHeaderCellSizeStyle(
|
|
41
|
+
header.id,
|
|
42
|
+
header.getSize(),
|
|
43
|
+
isExplicitColumnWidth(header.column, resizeSizingReady ? columnSizing : {}),
|
|
44
|
+
!!resizeSizingReady,
|
|
45
|
+
)}
|
|
40
46
|
/>
|
|
41
47
|
);
|
|
42
48
|
}
|
|
@@ -45,8 +51,14 @@ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
|
45
51
|
return <DsTableGroupHeaderCell key={header.id} header={header} />;
|
|
46
52
|
}
|
|
47
53
|
|
|
48
|
-
const headerStyle =
|
|
54
|
+
const headerStyle = getHeaderCellSizeStyle(
|
|
55
|
+
header.id,
|
|
56
|
+
header.column.getSize(),
|
|
57
|
+
isExplicitColumnWidth(header.column, resizeSizingReady ? columnSizing : {}),
|
|
58
|
+
!!resizeSizingReady,
|
|
59
|
+
);
|
|
49
60
|
const canSort = header.column.getCanSort();
|
|
61
|
+
const canResize = resizableColumns && header.column.getCanResize();
|
|
50
62
|
const isSelectColumn = header.column.id === SELECT_COLUMN_ID;
|
|
51
63
|
const isGroupStart = isFirstLeafColumnOfGroup(header.column);
|
|
52
64
|
|
|
@@ -58,6 +70,7 @@ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
|
58
70
|
return (
|
|
59
71
|
<TableHead
|
|
60
72
|
key={header.id}
|
|
73
|
+
data-column-id={header.column.id}
|
|
61
74
|
className={classnames(
|
|
62
75
|
styles.headerCell,
|
|
63
76
|
canSort && styles.sortableHeader,
|
|
@@ -70,8 +83,15 @@ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
|
70
83
|
style={headerStyle}
|
|
71
84
|
>
|
|
72
85
|
<div className={styles.headerSortContainer}>
|
|
73
|
-
<DsStack
|
|
74
|
-
|
|
86
|
+
<DsStack
|
|
87
|
+
direction="column"
|
|
88
|
+
justifyContent="center"
|
|
89
|
+
width="100%"
|
|
90
|
+
className={styles.headerLabelStack}
|
|
91
|
+
>
|
|
92
|
+
<span className={styles.headerLabel}>
|
|
93
|
+
{flexRender(header.column.columnDef.header, header.getContext())}
|
|
94
|
+
</span>
|
|
75
95
|
</DsStack>
|
|
76
96
|
{canSort && (
|
|
77
97
|
<div className={styles.pageButtonIconContainer}>
|
|
@@ -106,6 +126,7 @@ const DsTableHeader = <TData,>({ table }: DsTableHeaderProps<TData>) => {
|
|
|
106
126
|
</div>
|
|
107
127
|
)}
|
|
108
128
|
</div>
|
|
129
|
+
{canResize && <DsTableResizeHandle header={header} />}
|
|
109
130
|
</TableHead>
|
|
110
131
|
);
|
|
111
132
|
})}
|
package/src/components/ds-table/components/ds-table-resize-handle/ds-table-resize-handle.module.scss
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
@use '../../styles/variables' as vars;
|
|
2
|
+
|
|
3
|
+
.resizeHandle {
|
|
4
|
+
position: absolute;
|
|
5
|
+
top: 0;
|
|
6
|
+
// Overlay paints 2px from the cell right edge; center this hit target on that band.
|
|
7
|
+
right: vars.$resize-handle-hit-width * -0.5 + vars.$resize-divider-width * -0.5;
|
|
8
|
+
height: 100%;
|
|
9
|
+
width: vars.$resize-handle-hit-width;
|
|
10
|
+
padding: 0;
|
|
11
|
+
border: 0;
|
|
12
|
+
background: transparent;
|
|
13
|
+
cursor: col-resize;
|
|
14
|
+
touch-action: none;
|
|
15
|
+
z-index: 1;
|
|
16
|
+
|
|
17
|
+
// Focusable for keyboard resize (WCAG 2.1.1). Negative offset keeps the ring
|
|
18
|
+
// clear of the scroll container's overflow clip on the last column.
|
|
19
|
+
&:focus-visible {
|
|
20
|
+
outline: vars.$resize-divider-width solid var(--border-action-primary);
|
|
21
|
+
outline-offset: -1px;
|
|
22
|
+
}
|
|
23
|
+
}
|