@juwel-development/design-system 3.9.0 → 3.9.1
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/design-system.js
CHANGED
|
@@ -1119,24 +1119,34 @@ var g = (e) => typeof e == "boolean" ? `${e}` : e === 0 ? "0" : e, _ = h, v = (e
|
|
|
1119
1119
|
if (e.min >= e.max) throw new X(`\`min\` (${e.min}) must be below \`max\` (${e.max})`);
|
|
1120
1120
|
if (e.step <= 0) throw new X(`\`step\` (${e.step}) must be positive`);
|
|
1121
1121
|
if (e.value < e.min || e.value > e.max) throw new X(`\`value\` (${e.value}) must lie within [${e.min}, ${e.max}]`);
|
|
1122
|
-
}, ft = ({ min:
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1122
|
+
}, ft = ({ min: n, max: r, step: i = 1, value: a, onInput$: o, label: s, valueText: c, disabled: u, testId: d }) => {
|
|
1123
|
+
let f = `${l()}-control`;
|
|
1124
|
+
return dt({
|
|
1125
|
+
min: n,
|
|
1126
|
+
max: r,
|
|
1127
|
+
step: i,
|
|
1128
|
+
value: a
|
|
1129
|
+
}), /* @__PURE__ */ t("div", {
|
|
1130
|
+
className: "flex flex-col gap-[var(--space-stack)]",
|
|
1131
|
+
children: [/* @__PURE__ */ e("label", {
|
|
1132
|
+
htmlFor: f,
|
|
1133
|
+
className: "font-secondary font-medium text-body text-foreground",
|
|
1134
|
+
children: s
|
|
1135
|
+
}), /* @__PURE__ */ e("input", {
|
|
1136
|
+
id: f,
|
|
1137
|
+
type: "range",
|
|
1138
|
+
className: ut(),
|
|
1139
|
+
min: n,
|
|
1140
|
+
max: r,
|
|
1141
|
+
step: i,
|
|
1142
|
+
value: a,
|
|
1143
|
+
disabled: u,
|
|
1144
|
+
"aria-valuetext": c,
|
|
1145
|
+
"data-testid": d,
|
|
1146
|
+
onChange: (e) => o.next(e.currentTarget.valueAsNumber)
|
|
1147
|
+
})]
|
|
1148
|
+
});
|
|
1149
|
+
}, pt = class extends Error {
|
|
1140
1150
|
constructor(e) {
|
|
1141
1151
|
super(`Tabs.${e} must be composed inside Tabs.Root`), this.name = "TabsCompositionError";
|
|
1142
1152
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type FunctionComponent } from 'react';
|
|
2
2
|
import type { Subject } from 'rxjs';
|
|
3
3
|
export interface ISliderProps {
|
|
4
4
|
/** The operating range's lower bound - interaction geometry, not a content rule (ADR 0009). */
|
|
@@ -20,7 +20,10 @@ export interface ISliderProps {
|
|
|
20
20
|
* could never read a value at all.
|
|
21
21
|
*/
|
|
22
22
|
onInput$: Subject<number>;
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Always rendered as a visible label associated with the control, the way `Input`'s is (#112);
|
|
25
|
+
* it doubles as the accessible name.
|
|
26
|
+
*/
|
|
24
27
|
label: string;
|
|
25
28
|
/**
|
|
26
29
|
* How the value is announced, in the consumer's wording ("$60 a week"). Left out, assistive
|
|
@@ -35,7 +38,9 @@ export interface ISliderProps {
|
|
|
35
38
|
* A control that sets one numeric value by moving one thumb along a fixed, visible operating
|
|
36
39
|
* range. Controlled: the consumer holds the value and passes it back in, and a value it does not
|
|
37
40
|
* pass back is never adopted. It renders the value nowhere - the consumer sets any figures beside
|
|
38
|
-
* it with typography - and it fills its container's width the way `Input` does.
|
|
39
|
-
*
|
|
41
|
+
* it with typography - and it fills its container's width the way `Input` does. Its label follows
|
|
42
|
+
* `Input` too: visible, associated, and the only text the component renders (#112). It is still
|
|
43
|
+
* a live control and not a form field, so none of Input's annotations - hint, error, optional
|
|
44
|
+
* marker - come with it. `disabled` is the explicit non-operable state.
|
|
40
45
|
*/
|
|
41
46
|
export declare const Slider: FunctionComponent<ISliderProps>;
|
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { cva } from 'class-variance-authority';
|
|
2
|
-
import type
|
|
2
|
+
import { type FunctionComponent, useId } from 'react';
|
|
3
3
|
import type { Subject } from 'rxjs';
|
|
4
4
|
import { SliderConfigurationError } from './SliderConfigurationError';
|
|
5
5
|
|
|
@@ -45,7 +45,10 @@ export interface ISliderProps {
|
|
|
45
45
|
* could never read a value at all.
|
|
46
46
|
*/
|
|
47
47
|
onInput$: Subject<number>;
|
|
48
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* Always rendered as a visible label associated with the control, the way `Input`'s is (#112);
|
|
50
|
+
* it doubles as the accessible name.
|
|
51
|
+
*/
|
|
49
52
|
label: string;
|
|
50
53
|
/**
|
|
51
54
|
* How the value is announced, in the consumer's wording ("$60 a week"). Left out, assistive
|
|
@@ -91,8 +94,10 @@ const assertOperatingRange = (
|
|
|
91
94
|
* A control that sets one numeric value by moving one thumb along a fixed, visible operating
|
|
92
95
|
* range. Controlled: the consumer holds the value and passes it back in, and a value it does not
|
|
93
96
|
* pass back is never adopted. It renders the value nowhere - the consumer sets any figures beside
|
|
94
|
-
* it with typography - and it fills its container's width the way `Input` does.
|
|
95
|
-
*
|
|
97
|
+
* it with typography - and it fills its container's width the way `Input` does. Its label follows
|
|
98
|
+
* `Input` too: visible, associated, and the only text the component renders (#112). It is still
|
|
99
|
+
* a live control and not a form field, so none of Input's annotations - hint, error, optional
|
|
100
|
+
* marker - come with it. `disabled` is the explicit non-operable state.
|
|
96
101
|
*/
|
|
97
102
|
export const Slider: FunctionComponent<ISliderProps> = ({
|
|
98
103
|
min,
|
|
@@ -105,21 +110,32 @@ export const Slider: FunctionComponent<ISliderProps> = ({
|
|
|
105
110
|
disabled,
|
|
106
111
|
testId,
|
|
107
112
|
}) => {
|
|
113
|
+
const controlId = `${useId()}-control`;
|
|
108
114
|
assertOperatingRange({ min, max, step, value });
|
|
109
115
|
return (
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
116
|
+
<div className={'flex flex-col gap-[var(--space-stack)]'}>
|
|
117
|
+
{/* The label declares its face and size on itself, never on the wrapper, which would hand
|
|
118
|
+
them to the control too; `body` is the control's own role (docs/adr/0004, #90, #92). */}
|
|
119
|
+
<label
|
|
120
|
+
htmlFor={controlId}
|
|
121
|
+
className={'font-secondary font-medium text-body text-foreground'}
|
|
122
|
+
>
|
|
123
|
+
{label}
|
|
124
|
+
</label>
|
|
125
|
+
<input
|
|
126
|
+
id={controlId}
|
|
127
|
+
type={'range'}
|
|
128
|
+
className={slider()}
|
|
129
|
+
min={min}
|
|
130
|
+
max={max}
|
|
131
|
+
step={step}
|
|
132
|
+
value={value}
|
|
133
|
+
disabled={disabled}
|
|
134
|
+
aria-valuetext={valueText}
|
|
135
|
+
data-testid={testId}
|
|
136
|
+
// React's onChange rides the native input event, so every movement emits through here.
|
|
137
|
+
onChange={(event) => onInput$.next(event.currentTarget.valueAsNumber)}
|
|
138
|
+
/>
|
|
139
|
+
</div>
|
|
124
140
|
);
|
|
125
141
|
};
|