oneslash-design-system 2.0.1 → 2.0.3

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.
@@ -1,5 +1,9 @@
1
1
  import React from 'react';
2
- interface ButtonProps {
2
+ /** `aria-*`, `data-*`, `id` and `title` are forwarded to the rendered `<button>` */
3
+ interface ButtonProps extends React.AriaAttributes {
4
+ id?: string;
5
+ title?: string;
6
+ [dataAttr: `data-${string}`]: string | number | boolean | undefined;
3
7
  size: 'tiny' | 'small' | 'medium' | 'large';
4
8
  type: 'primary' | 'secondary' | 'tertiary' | 'textOnly';
5
9
  color?: 'default' | 'danger';
@@ -14,5 +18,5 @@ interface ButtonProps {
14
18
  /** Shows a spinner in the icon slot, keeps the label, and disables the button */
15
19
  loading?: boolean;
16
20
  }
17
- export default function Button({ size, type, color, state, label, secondLabel, decoIcon, actionIcon, onClickButton, onClickActionIcon, className, loading, }: ButtonProps): React.JSX.Element;
21
+ export default function Button({ size, type, color, state, label, secondLabel, decoIcon, actionIcon, onClickButton, onClickActionIcon, className, loading, ...rest }: ButtonProps): React.JSX.Element;
18
22
  export {};
@@ -1,10 +1,21 @@
1
1
  'use client';
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  import React from 'react';
3
14
  import * as LucideIcons from 'lucide-react';
4
15
  import { LoadingSmall } from './loadingScreen';
5
16
  import { focusRing, focusRingDanger, pressFeedback, stateTransition } from './sharedStyles';
6
17
  export default function Button(_a) {
7
- var size = _a.size, type = _a.type, _b = _a.color, color = _b === void 0 ? 'default' : _b, state = _a.state, label = _a.label, secondLabel = _a.secondLabel, decoIcon = _a.decoIcon, actionIcon = _a.actionIcon, onClickButton = _a.onClickButton, onClickActionIcon = _a.onClickActionIcon, _c = _a.className, className = _c === void 0 ? '' : _c, _d = _a.loading, loading = _d === void 0 ? false : _d;
18
+ var size = _a.size, type = _a.type, _b = _a.color, color = _b === void 0 ? 'default' : _b, state = _a.state, label = _a.label, secondLabel = _a.secondLabel, decoIcon = _a.decoIcon, actionIcon = _a.actionIcon, onClickButton = _a.onClickButton, onClickActionIcon = _a.onClickActionIcon, _c = _a.className, className = _c === void 0 ? '' : _c, _d = _a.loading, loading = _d === void 0 ? false : _d, rest = __rest(_a, ["size", "type", "color", "state", "label", "secondLabel", "decoIcon", "actionIcon", "onClickButton", "onClickActionIcon", "className", "loading"]);
8
19
  // Synchronous lookup so icons render on the first paint
9
20
  var IconLeft = decoIcon ? LucideIcons[decoIcon] : null;
10
21
  var IconRight = actionIcon ? LucideIcons[actionIcon] : null;
@@ -67,7 +78,7 @@ export default function Button(_a) {
67
78
  };
68
79
  // Hover is pure CSS; `state="hovered"` and `state="focused"` only exist to show those states in docs
69
80
  var buttonClasses = "\n flex flex-row items-center rounded-control justify-between ".concat(stateTransition, " ").concat(pressFeedback, "\n ").concat(color === 'danger' ? focusRingDanger : focusRing, "\n ").concat(sizeClasses, "\n ").concat(state === 'selected' ? stateClasses.selected : '', "\n ").concat(state === 'enabled' || state === 'hovered' ? "".concat(baseTypeClasses, " ").concat(loading ? 'cursor-wait' : "".concat(stateClasses.enabled, " ").concat(hoverTypeClasses)) : '', "\n ").concat(state === 'focused' ? "".concat(baseTypeClasses, " ").concat(hoverTypeClasses, " ").concat(stateClasses.focused) : '', "\n ").concat(state === 'disabled' ? stateClasses.disabled : '', "\n ").concat(className, "\n ");
70
- return (<button type="button" className={buttonClasses} disabled={state === 'disabled' || loading} aria-busy={loading || undefined} onClick={onClickButton}>
81
+ return (<button {...rest} type="button" className={buttonClasses} disabled={state === 'disabled' || loading} aria-busy={loading || undefined} onClick={onClickButton}>
71
82
  {/* Group IconLeft and label in a flex container for left alignment */}
72
83
  <div className={"flex items-center ".concat(size === 'tiny' ? 'gap-0.5' : 'gap-1')}>
73
84
  {loading ? (<LoadingSmall size={spinnerSize}/>) : (IconLeft && <IconLeft className={"".concat(sizeIcon, " flex-shrink-0")} strokeWidth={2}/>)}
@@ -1,6 +1,10 @@
1
1
  import React from 'react';
2
2
  import * as LucideIcons from 'lucide-react';
3
- interface IconButtonProps {
3
+ /** `aria-*`, `data-*`, `id` and `title` are forwarded to the rendered `<button>` */
4
+ interface IconButtonProps extends React.AriaAttributes {
5
+ id?: string;
6
+ title?: string;
7
+ [dataAttr: `data-${string}`]: string | number | boolean | undefined;
4
8
  color: "primary" | "secondary" | "tertiary" | "iconOnly";
5
9
  state: "enabled" | "selected" | "disabled";
6
10
  size: "large" | "medium" | "small" | "tiny";
@@ -11,5 +15,5 @@ interface IconButtonProps {
11
15
  ariaLabel?: string;
12
16
  }
13
17
  export default function IconButton({ color, state, size, iconName, onClick, loading, // Default to false
14
- ariaLabel, }: IconButtonProps): React.JSX.Element;
18
+ ariaLabel, ...rest }: IconButtonProps): React.JSX.Element;
15
19
  export {};
@@ -1,11 +1,22 @@
1
1
  'use client';
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
2
13
  import React from 'react';
3
14
  import * as LucideIcons from 'lucide-react';
4
15
  import { LoadingSmall } from './loadingScreen';
5
16
  import { focusRing, pressFeedback, stateTransition } from './sharedStyles';
6
17
  export default function IconButton(_a) {
7
18
  var color = _a.color, state = _a.state, size = _a.size, iconName = _a.iconName, onClick = _a.onClick, _b = _a.loading, loading = _b === void 0 ? false : _b, // Default to false
8
- ariaLabel = _a.ariaLabel;
19
+ ariaLabel = _a.ariaLabel, rest = __rest(_a, ["color", "state", "size", "iconName", "onClick", "loading", "ariaLabel"]);
9
20
  var Icon = LucideIcons[iconName];
10
21
  // "ChevronDown" -> "Chevron Down"
11
22
  var label = ariaLabel !== null && ariaLabel !== void 0 ? ariaLabel : String(iconName).replace(/([a-z])([A-Z0-9])/g, '$1 $2');
@@ -67,7 +78,7 @@ export default function IconButton(_a) {
67
78
  : state === 'selected'
68
79
  ? 'cursor-pointer'
69
80
  : 'cursor-pointer';
70
- return (<button type="button" className={"".concat(baseClasses, " ").concat(bgColor, " ").concat(iconColor, " ").concat(bgColorHover, " ").concat(stateClasses, " ").concat(stateTransition, " ").concat(pressFeedback, " ").concat(focusRing, " flex items-center justify-center")} disabled={isDisabled || loading} // Disable button during loading
81
+ return (<button {...rest} type="button" className={"".concat(baseClasses, " ").concat(bgColor, " ").concat(iconColor, " ").concat(bgColorHover, " ").concat(stateClasses, " ").concat(stateTransition, " ").concat(pressFeedback, " ").concat(focusRing, " flex items-center justify-center")} disabled={isDisabled || loading} // Disable button during loading
71
82
  onClick={onClick} aria-label={loading ? 'Loading' : label}>
72
83
  {loading ? (<LoadingSmall size={size}/>) : (Icon && <Icon className={iconSizeClasses[size]} strokeWidth={2}/>)}
73
84
  </button>);
@@ -10,6 +10,8 @@ interface TagProps {
10
10
  secondLabel?: string;
11
11
  iconName?: IconName;
12
12
  onClick?: React.MouseEventHandler<HTMLDivElement>;
13
+ /** Only applies to a clickable tag: dims it, drops it from the tab order and ignores clicks */
14
+ disabled?: boolean;
13
15
  }
14
- export default function Tag({ variant, size, state, color, label, secondLabel, iconName, onClick, }: TagProps): JSX.Element;
16
+ export default function Tag({ variant, size, state, color, label, secondLabel, iconName, onClick, disabled, }: TagProps): JSX.Element;
15
17
  export {};
@@ -47,7 +47,7 @@ var colorConfig = {
47
47
  },
48
48
  };
49
49
  export default function Tag(_a) {
50
- var variant = _a.variant, size = _a.size, _b = _a.state, state = _b === void 0 ? 'enabled' : _b, color = _a.color, label = _a.label, secondLabel = _a.secondLabel, iconName = _a.iconName, onClick = _a.onClick;
50
+ var variant = _a.variant, size = _a.size, _b = _a.state, state = _b === void 0 ? 'enabled' : _b, color = _a.color, label = _a.label, secondLabel = _a.secondLabel, iconName = _a.iconName, onClick = _a.onClick, _c = _a.disabled, disabled = _c === void 0 ? false : _c;
51
51
  // Get icon directly from icons map
52
52
  var Icon = iconName ? icons[iconName] : null;
53
53
  // Size and padding
@@ -114,20 +114,22 @@ export default function Tag(_a) {
114
114
  }
115
115
  // Dot color
116
116
  var dotColor = (colorStyles === null || colorStyles === void 0 ? void 0 : colorStyles.dot) || colorConfig.default.dot;
117
- // Hover (only when not selected, no color, and onClick is provided)
118
- var hoverClasses = !isSelected && !color && variant === 'contained' && onClick
117
+ var isDisabled = !!onClick && disabled;
118
+ // Hover (only when not selected, not disabled, no color, and onClick is provided)
119
+ var hoverClasses = !isSelected && !isDisabled && !color && variant === 'contained' && onClick
119
120
  ? 'hover:bg-background-accent200'
120
121
  : '';
121
- var cursorClass = onClick && !isSelected ? 'cursor-pointer' : '';
122
+ var cursorClass = isDisabled ? 'cursor-not-allowed opacity-50' : onClick && !isSelected ? 'cursor-pointer' : '';
122
123
  // inline-flex so a tag wraps its content instead of stretching to its container
123
124
  var baseClasses = "inline-flex items-center gap-1 rounded-full whitespace-nowrap ".concat(stateTransition);
124
125
  // A clickable tag is a keyboard-reachable toggle button
125
126
  var interactiveProps = onClick
126
127
  ? {
127
128
  role: 'button',
128
- tabIndex: 0,
129
+ tabIndex: isDisabled ? -1 : 0,
129
130
  'aria-pressed': isSelected,
130
- onClick: onClick,
131
+ 'aria-disabled': isDisabled || undefined,
132
+ onClick: isDisabled ? undefined : onClick,
131
133
  onKeyDown: function (e) {
132
134
  if (e.key === 'Enter' || e.key === ' ') {
133
135
  e.preventDefault();
@@ -136,7 +138,7 @@ export default function Tag(_a) {
136
138
  },
137
139
  }
138
140
  : {};
139
- return (<div className={"".concat(baseClasses, " ").concat(sizeClasses, " ").concat(bgClasses, " ").concat(fontClasses, " ").concat(borderClasses, " ").concat(hoverClasses, " ").concat(cursorClass, " ").concat(onClick ? "".concat(focusRing, " ").concat(pressFeedbackAny) : '')} {...interactiveProps}>
141
+ return (<div className={"".concat(baseClasses, " ").concat(sizeClasses, " ").concat(bgClasses, " ").concat(fontClasses, " ").concat(borderClasses, " ").concat(hoverClasses, " ").concat(cursorClass, " ").concat(onClick ? focusRing : '', " ").concat(onClick && !isDisabled ? pressFeedbackAny : '')} {...interactiveProps}>
140
142
  {variant === 'dot' && (<span className={"w-3 h-3 rounded-full flex-shrink-0 ".concat(dotColor)}/>)}
141
143
  {Icon && variant !== 'dot' && <Icon className={"".concat(size === 'tiny' ? 'w-3 h-3' : 'w-4 h-4', " flex-shrink-0")} strokeWidth={2}/>}
142
144
  <div className="flex flex-col text-center">
@@ -19,6 +19,10 @@ interface TextFieldProps {
19
19
  required?: boolean;
20
20
  size?: 'large' | 'medium' | 'small' | 'tiny';
21
21
  placeholder?: string;
22
+ name?: string;
23
+ /** Browser autofill hint, e.g. "username" or "current-password". Defaults to "off". */
24
+ autoComplete?: string;
25
+ tabIndex?: number;
22
26
  }
23
- export default function TextField({ id, label, value, type, onChange, onBlur, onFocus, onKeyDown, onSubmit, autoFocus, multiline, maxRows, disabled, error, errorText, required, size, placeholder, }: TextFieldProps): React.JSX.Element;
27
+ export default function TextField({ id, label, value, type, onChange, onBlur, onFocus, onKeyDown, onSubmit, autoFocus, multiline, maxRows, disabled, error, errorText, required, size, placeholder, name, autoComplete, tabIndex, }: TextFieldProps): React.JSX.Element;
24
28
  export {};
@@ -2,7 +2,7 @@
2
2
  import React from 'react';
3
3
  import { stateTransition } from './sharedStyles';
4
4
  export default function TextField(_a) {
5
- var id = _a.id, label = _a.label, value = _a.value, _b = _a.type, type = _b === void 0 ? 'text' : _b, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown, onSubmit = _a.onSubmit, _c = _a.autoFocus, autoFocus = _c === void 0 ? false : _c, _d = _a.multiline, multiline = _d === void 0 ? false : _d, _e = _a.maxRows, maxRows = _e === void 0 ? 6 : _e, _f = _a.disabled, disabled = _f === void 0 ? false : _f, _g = _a.error, error = _g === void 0 ? false : _g, _h = _a.errorText, errorText = _h === void 0 ? 'This field is required' : _h, _j = _a.required, required = _j === void 0 ? false : _j, _k = _a.size, size = _k === void 0 ? 'medium' : _k, placeholder = _a.placeholder;
5
+ var id = _a.id, label = _a.label, value = _a.value, _b = _a.type, type = _b === void 0 ? 'text' : _b, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown, onSubmit = _a.onSubmit, _c = _a.autoFocus, autoFocus = _c === void 0 ? false : _c, _d = _a.multiline, multiline = _d === void 0 ? false : _d, _e = _a.maxRows, maxRows = _e === void 0 ? 6 : _e, _f = _a.disabled, disabled = _f === void 0 ? false : _f, _g = _a.error, error = _g === void 0 ? false : _g, _h = _a.errorText, errorText = _h === void 0 ? 'This field is required' : _h, _j = _a.required, required = _j === void 0 ? false : _j, _k = _a.size, size = _k === void 0 ? 'medium' : _k, placeholder = _a.placeholder, name = _a.name, _l = _a.autoComplete, autoComplete = _l === void 0 ? 'off' : _l, tabIndex = _a.tabIndex;
6
6
  var handleKeyDown = function (e) {
7
7
  // Ctrl+Enter or Cmd+Enter to submit
8
8
  if ((e.ctrlKey || e.metaKey) && e.key === 'Enter' && onSubmit) {
@@ -59,12 +59,12 @@ export default function TextField(_a) {
59
59
  };
60
60
  return (<div className="flex flex-col w-full">
61
61
  {label && (<label htmlFor={id} className="mb-1 text-body2 text-fg-secondary">
62
- {label}{required && <span className="text-error-main ml-0.5">*</span>}
62
+ {label}{required && <span className="text-error-text ml-0.5">*</span>}
63
63
  </label>)}
64
64
  <div className="relative">
65
- {multiline ? (<textarea id={id} rows={maxRows} className={containerClasses} value={value} onChange={onChange} placeholder={placeholder} onFocus={onFocus} onBlur={onBlur} onKeyDown={handleKeyDown} autoFocus={autoFocus} disabled={disabled} required={required} autoComplete="off" {...errorProps}/>) : (<input id={id} type={type} inputMode={getInputMode()} className={containerClasses} value={value} onChange={onChange} placeholder={placeholder} onFocus={onFocus} onBlur={onBlur} onKeyDown={handleKeyDown} autoFocus={autoFocus} disabled={disabled} required={required} autoComplete="off" {...errorProps}/>)}
65
+ {multiline ? (<textarea id={id} rows={maxRows} className={containerClasses} value={value} onChange={onChange} placeholder={placeholder} onFocus={onFocus} onBlur={onBlur} onKeyDown={handleKeyDown} autoFocus={autoFocus} disabled={disabled} required={required} name={name} autoComplete={autoComplete} tabIndex={tabIndex} {...errorProps}/>) : (<input id={id} type={type} inputMode={getInputMode()} className={containerClasses} value={value} onChange={onChange} placeholder={placeholder} onFocus={onFocus} onBlur={onBlur} onKeyDown={handleKeyDown} autoFocus={autoFocus} disabled={disabled} required={required} name={name} autoComplete={autoComplete} tabIndex={tabIndex} {...errorProps}/>)}
66
66
  </div>
67
- {error && (<p id={errorId} className="mt-1 text-error-main text-body2">
67
+ {error && (<p id={errorId} className="mt-1 text-error-text text-body2">
68
68
  {errorText}
69
69
  </p>)}
70
70
  </div>);
@@ -18,6 +18,10 @@ interface TextareaProps {
18
18
  errorText?: string;
19
19
  size?: 'medium' | 'small' | 'tiny';
20
20
  placeholder?: string;
21
+ name?: string;
22
+ /** Browser autofill hint. Defaults to "off". */
23
+ autoComplete?: string;
24
+ tabIndex?: number;
21
25
  }
22
- export default function Textarea({ id, label, value, onChange, onBlur, onFocus, onKeyDown, onCompositionStart, onCompositionEnd, onSubmit, autoFocus, maxRows, disabled, error, errorText, size, placeholder, }: TextareaProps): React.JSX.Element;
26
+ export default function Textarea({ id, label, value, onChange, onBlur, onFocus, onKeyDown, onCompositionStart, onCompositionEnd, onSubmit, autoFocus, maxRows, disabled, error, errorText, size, placeholder, name, autoComplete, tabIndex, }: TextareaProps): React.JSX.Element;
23
27
  export {};
@@ -2,7 +2,7 @@
2
2
  import React, { useCallback, useEffect, useRef } from 'react';
3
3
  import { stateTransition } from './sharedStyles';
4
4
  export default function Textarea(_a) {
5
- var id = _a.id, label = _a.label, value = _a.value, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown, onCompositionStart = _a.onCompositionStart, onCompositionEnd = _a.onCompositionEnd, onSubmit = _a.onSubmit, _b = _a.autoFocus, autoFocus = _b === void 0 ? false : _b, _c = _a.maxRows, maxRows = _c === void 0 ? 6 : _c, _d = _a.disabled, disabled = _d === void 0 ? false : _d, _e = _a.error, error = _e === void 0 ? false : _e, _f = _a.errorText, errorText = _f === void 0 ? 'This field is required' : _f, _g = _a.size, size = _g === void 0 ? 'medium' : _g, placeholder = _a.placeholder;
5
+ var id = _a.id, label = _a.label, value = _a.value, onChange = _a.onChange, onBlur = _a.onBlur, onFocus = _a.onFocus, onKeyDown = _a.onKeyDown, onCompositionStart = _a.onCompositionStart, onCompositionEnd = _a.onCompositionEnd, onSubmit = _a.onSubmit, _b = _a.autoFocus, autoFocus = _b === void 0 ? false : _b, _c = _a.maxRows, maxRows = _c === void 0 ? 6 : _c, _d = _a.disabled, disabled = _d === void 0 ? false : _d, _e = _a.error, error = _e === void 0 ? false : _e, _f = _a.errorText, errorText = _f === void 0 ? 'This field is required' : _f, _g = _a.size, size = _g === void 0 ? 'medium' : _g, placeholder = _a.placeholder, name = _a.name, _h = _a.autoComplete, autoComplete = _h === void 0 ? 'off' : _h, tabIndex = _a.tabIndex;
6
6
  var textareaRef = useRef(null);
7
7
  var handleKeyDown = function (e) {
8
8
  // Ctrl+Enter or Cmd+Enter to submit
@@ -65,9 +65,9 @@ export default function Textarea(_a) {
65
65
  {label}
66
66
  </label>)}
67
67
  <div className="relative">
68
- <textarea ref={textareaRef} id={id} rows={1} className={containerClasses} value={value} onChange={onChange} onInput={adjustHeight} placeholder={placeholder} onFocus={onFocus} onBlur={onBlur} onKeyDown={handleKeyDown} onCompositionStart={onCompositionStart} onCompositionEnd={onCompositionEnd} autoFocus={autoFocus} disabled={disabled} autoComplete="off" aria-invalid={error || undefined} aria-describedby={error ? errorId : undefined}/>
68
+ <textarea ref={textareaRef} id={id} rows={1} className={containerClasses} value={value} onChange={onChange} onInput={adjustHeight} placeholder={placeholder} onFocus={onFocus} onBlur={onBlur} onKeyDown={handleKeyDown} onCompositionStart={onCompositionStart} onCompositionEnd={onCompositionEnd} autoFocus={autoFocus} disabled={disabled} name={name} autoComplete={autoComplete} tabIndex={tabIndex} aria-invalid={error || undefined} aria-describedby={error ? errorId : undefined}/>
69
69
  </div>
70
- {error && (<p id={errorId} className="mt-1 text-error-main text-body2">
70
+ {error && (<p id={errorId} className="mt-1 text-error-text text-body2">
71
71
  {errorText}
72
72
  </p>)}
73
73
  </div>);
@@ -39,7 +39,7 @@ var base = {
39
39
  },
40
40
  error: {
41
41
  main: '#D32F2F',
42
- dark: '#B22323',
42
+ dark: '#A82121', // 4.62:1 on alertBg (#B22323 was 4.27)
43
43
  light: '#F27777',
44
44
  alertBg: '#F2C4C4',
45
45
  contrast: '#FFFFFF',
@@ -126,7 +126,7 @@ var base = {
126
126
  dark: '#B22323',
127
127
  light: '#F27777',
128
128
  alertBg: '#5C1A1A',
129
- contrast: '#FFFFFF',
129
+ contrast: '#000000', // 5.5:1 on main (#FFFFFF was 3.79)
130
130
  },
131
131
  warning: {
132
132
  main: '#FF8C0A',
@@ -338,8 +338,8 @@ var forestDark = override(baseColors.dark, {
338
338
  * @returns {S}
339
339
  */
340
340
  var withForestInfoText = function (set) { return (__assign(__assign({}, set), { info: __assign(__assign({}, set.info), { text: '#0068A3', textHover: '#0068A3' }) })); };
341
- // Forest's secondary.main (#6E7A5A) is mid-tone: its text.primary gives 3.5:1, so the label is the pale green
342
- // Scindo's hand-written theme used (3.8:1 light, 3.5:1 dark; report-only in check:contrast).
341
+ // Forest's secondary.main (#6E7A5A) is mid-tone: its text.primary gives 3.5:1 and Scindo's cream 3.8:1, so the
342
+ // label is white (4.56:1) in both modes.
343
343
  /**
344
344
  * @template {typeof base.colors.light} S
345
345
  * @param {S} set
@@ -359,5 +359,5 @@ var withTooltips = function (light, dark) { return ({
359
359
  dark: __assign(__assign({}, dark), { misc: __assign(__assign({}, dark.misc), { tooltipBg: light.background.accent300, tooltipText: light.text.primary }) }),
360
360
  }); };
361
361
  var defaultSets = withTooltips(withSemanticKeys(baseColors.light, 'light'), withSemanticKeys(baseColors.dark, 'dark'));
362
- var forestSets = withTooltips(withSecondaryContrast(withForestInfoText(withSemanticKeys(forestLight, 'light')), '#E7ECDA'), withSecondaryContrast(withSemanticKeys(forestDark, 'dark'), '#D9E5C7'));
362
+ var forestSets = withTooltips(withSecondaryContrast(withForestInfoText(withSemanticKeys(forestLight, 'light')), '#FFFFFF'), withSecondaryContrast(withSemanticKeys(forestDark, 'dark'), '#FFFFFF'));
363
363
  module.exports = __assign(__assign({}, base), { colors: defaultSets, themes: { forest: forestSets } });
@@ -17,3 +17,4 @@ export declare const DangerTertiary: Story;
17
17
  export declare const DangerTextOnly: Story;
18
18
  export declare const DangerVariants: Story;
19
19
  export declare const Loading: Story;
20
+ export declare const AriaExpanded: Story;
@@ -146,3 +146,18 @@ export var Loading = {
146
146
  <Button size="tiny" type="textOnly" state="enabled" label="Saving" loading/>
147
147
  </div>); },
148
148
  };
149
+ // `aria-*`, `data-*`, `id` and `title` reach the <button>, so an app can mark a toggle
150
+ export var AriaExpanded = {
151
+ args: {
152
+ size: "medium",
153
+ type: "secondary",
154
+ state: "enabled",
155
+ label: "Filters",
156
+ actionIcon: "ChevronDown",
157
+ id: "filters-trigger",
158
+ title: "Show filters",
159
+ "aria-expanded": false,
160
+ "aria-controls": "filters-panel",
161
+ "data-testid": "filters-trigger",
162
+ },
163
+ };
@@ -11,3 +11,4 @@ export declare const Selected: Story;
11
11
  export declare const Disabled: Story;
12
12
  export declare const Loading: Story;
13
13
  export declare const AllSizes: Story;
14
+ export declare const AriaExpanded: Story;
@@ -86,3 +86,18 @@ export var AllSizes = {
86
86
  <IconButton color="primary" state="enabled" size="large" iconName="Star"/>
87
87
  </div>); },
88
88
  };
89
+ // `aria-*`, `data-*`, `id` and `title` reach the <button>, so an app can mark a toggle
90
+ export var AriaExpanded = {
91
+ args: {
92
+ color: "iconOnly",
93
+ state: "enabled",
94
+ size: "medium",
95
+ iconName: "ChevronDown",
96
+ ariaLabel: "Show details",
97
+ id: "details-trigger",
98
+ title: "Show details",
99
+ "aria-expanded": true,
100
+ "aria-controls": "details-panel",
101
+ "data-testid": "details-trigger",
102
+ },
103
+ };
@@ -9,6 +9,7 @@ export declare const Selected: Story;
9
9
  export declare const WithIcon: Story;
10
10
  export declare const Small: Story;
11
11
  export declare const Clickable: Story;
12
+ export declare const ClickableDisabled: Story;
12
13
  export declare const AllVariants: Story;
13
14
  export declare const Success: Story;
14
15
  export declare const Warning: Story;
@@ -80,6 +80,17 @@ export var Clickable = {
80
80
  onClick: function () { return alert("Tag clicked!"); },
81
81
  },
82
82
  };
83
+ // A clickable tag with `disabled`: dimmed, aria-disabled, out of the tab order, clicks ignored
84
+ export var ClickableDisabled = {
85
+ args: {
86
+ variant: "contained",
87
+ size: "medium",
88
+ state: "enabled",
89
+ label: "Unavailable",
90
+ onClick: function () { return alert("Should not fire"); },
91
+ disabled: true,
92
+ },
93
+ };
83
94
  export var AllVariants = {
84
95
  render: function () { return (<div style={{ display: "flex", gap: "8px", flexWrap: "wrap", alignItems: "center" }}>
85
96
  <Tag variant="contained" size="medium" label="Contained"/>
@@ -15,3 +15,4 @@ export declare const Email: Story;
15
15
  export declare const Password: Story;
16
16
  export declare const Required: Story;
17
17
  export declare const Number: Story;
18
+ export declare const Autofill: Story;
@@ -143,3 +143,16 @@ export var Number = {
143
143
  size: "medium",
144
144
  },
145
145
  };
146
+ // `name` and `autoComplete` let the browser autofill a login form; `tabIndex` reaches the input too
147
+ export var Autofill = {
148
+ render: function (args) { return <TextFieldWrapper {...args}/>; },
149
+ args: {
150
+ id: "autofill-textfield",
151
+ label: "Username",
152
+ value: "",
153
+ name: "username",
154
+ autoComplete: "username",
155
+ tabIndex: 0,
156
+ size: "medium",
157
+ },
158
+ };
@@ -10,3 +10,4 @@ export declare const WithError: Story;
10
10
  export declare const SmallSize: Story;
11
11
  export declare const AutoExpanding: Story;
12
12
  export declare const AllSizes: Story;
13
+ export declare const Named: Story;
@@ -82,3 +82,16 @@ export var AllSizes = {
82
82
  <TextareaWrapper id="size-medium" label="Medium" size="medium"/>
83
83
  </div>); },
84
84
  };
85
+ // `name`, `autoComplete` and `tabIndex` reach the <textarea>
86
+ export var Named = {
87
+ render: function (args) { return <TextareaWrapper {...args}/>; },
88
+ args: {
89
+ id: "named-textarea",
90
+ label: "Message",
91
+ value: "",
92
+ name: "message",
93
+ autoComplete: "off",
94
+ tabIndex: 0,
95
+ size: "medium",
96
+ },
97
+ };
@@ -20,14 +20,14 @@
20
20
  --os-color-secondary-light: 209 209 209;
21
21
  --os-color-secondary-contrast: 0 0 0;
22
22
  --os-color-error-main: 211 47 47;
23
- --os-color-error-dark: 178 35 35;
23
+ --os-color-error-dark: 168 33 33;
24
24
  --os-color-error-light: 242 119 119;
25
25
  --os-color-error-alertBg: 242 196 196;
26
26
  --os-color-error-contrast: 255 255 255;
27
- --os-color-error-fill: 178 35 35;
27
+ --os-color-error-fill: 168 33 33;
28
28
  --os-color-error-onFill: 255 255 255;
29
- --os-color-error-text: 178 35 35;
30
- --os-color-error-textHover: 178 35 35;
29
+ --os-color-error-text: 168 33 33;
30
+ --os-color-error-textHover: 168 33 33;
31
31
  --os-color-error-tint: 242 119 119;
32
32
  --os-color-warning-main: 239 108 0;
33
33
  --os-color-warning-dark: 168 70 0;
@@ -105,7 +105,7 @@
105
105
  --os-color-error-dark: 178 35 35;
106
106
  --os-color-error-light: 242 119 119;
107
107
  --os-color-error-alertBg: 92 26 26;
108
- --os-color-error-contrast: 255 255 255;
108
+ --os-color-error-contrast: 0 0 0;
109
109
  --os-color-error-fill: 231 76 76;
110
110
  --os-color-error-onFill: 0 0 0;
111
111
  --os-color-error-text: 242 119 119;
@@ -188,7 +188,7 @@
188
188
  --os-color-error-dark: 178 35 35;
189
189
  --os-color-error-light: 242 119 119;
190
190
  --os-color-error-alertBg: 92 26 26;
191
- --os-color-error-contrast: 255 255 255;
191
+ --os-color-error-contrast: 0 0 0;
192
192
  --os-color-error-fill: 231 76 76;
193
193
  --os-color-error-onFill: 0 0 0;
194
194
  --os-color-error-text: 242 119 119;
@@ -20,14 +20,14 @@
20
20
  --os-color-secondary-light: 209 209 209;
21
21
  --os-color-secondary-contrast: 0 0 0;
22
22
  --os-color-error-main: 211 47 47;
23
- --os-color-error-dark: 178 35 35;
23
+ --os-color-error-dark: 168 33 33;
24
24
  --os-color-error-light: 242 119 119;
25
25
  --os-color-error-alertBg: 242 196 196;
26
26
  --os-color-error-contrast: 255 255 255;
27
- --os-color-error-fill: 178 35 35;
27
+ --os-color-error-fill: 168 33 33;
28
28
  --os-color-error-onFill: 255 255 255;
29
- --os-color-error-text: 178 35 35;
30
- --os-color-error-textHover: 178 35 35;
29
+ --os-color-error-text: 168 33 33;
30
+ --os-color-error-textHover: 168 33 33;
31
31
  --os-color-error-tint: 242 119 119;
32
32
  --os-color-warning-main: 239 108 0;
33
33
  --os-color-warning-dark: 168 70 0;
@@ -105,7 +105,7 @@
105
105
  --os-color-error-dark: 178 35 35;
106
106
  --os-color-error-light: 242 119 119;
107
107
  --os-color-error-alertBg: 92 26 26;
108
- --os-color-error-contrast: 255 255 255;
108
+ --os-color-error-contrast: 0 0 0;
109
109
  --os-color-error-fill: 231 76 76;
110
110
  --os-color-error-onFill: 0 0 0;
111
111
  --os-color-error-text: 242 119 119;
@@ -18,16 +18,16 @@
18
18
  --os-color-secondary-main: 110 122 90;
19
19
  --os-color-secondary-dark: 93 104 73;
20
20
  --os-color-secondary-light: 130 141 107;
21
- --os-color-secondary-contrast: 231 236 218;
21
+ --os-color-secondary-contrast: 255 255 255;
22
22
  --os-color-error-main: 211 47 47;
23
- --os-color-error-dark: 178 35 35;
23
+ --os-color-error-dark: 168 33 33;
24
24
  --os-color-error-light: 242 119 119;
25
25
  --os-color-error-alertBg: 242 196 196;
26
26
  --os-color-error-contrast: 255 255 255;
27
- --os-color-error-fill: 178 35 35;
27
+ --os-color-error-fill: 168 33 33;
28
28
  --os-color-error-onFill: 255 255 255;
29
- --os-color-error-text: 178 35 35;
30
- --os-color-error-textHover: 178 35 35;
29
+ --os-color-error-text: 168 33 33;
30
+ --os-color-error-textHover: 168 33 33;
31
31
  --os-color-error-tint: 242 119 119;
32
32
  --os-color-warning-main: 239 108 0;
33
33
  --os-color-warning-dark: 168 70 0;
@@ -100,12 +100,12 @@
100
100
  --os-color-secondary-main: 110 122 90;
101
101
  --os-color-secondary-dark: 93 104 73;
102
102
  --os-color-secondary-light: 130 141 107;
103
- --os-color-secondary-contrast: 217 229 199;
103
+ --os-color-secondary-contrast: 255 255 255;
104
104
  --os-color-error-main: 231 76 76;
105
105
  --os-color-error-dark: 178 35 35;
106
106
  --os-color-error-light: 242 119 119;
107
107
  --os-color-error-alertBg: 92 26 26;
108
- --os-color-error-contrast: 255 255 255;
108
+ --os-color-error-contrast: 0 0 0;
109
109
  --os-color-error-fill: 231 76 76;
110
110
  --os-color-error-onFill: 0 0 0;
111
111
  --os-color-error-text: 242 119 119;
@@ -183,12 +183,12 @@
183
183
  --os-color-secondary-main: 110 122 90;
184
184
  --os-color-secondary-dark: 93 104 73;
185
185
  --os-color-secondary-light: 130 141 107;
186
- --os-color-secondary-contrast: 217 229 199;
186
+ --os-color-secondary-contrast: 255 255 255;
187
187
  --os-color-error-main: 231 76 76;
188
188
  --os-color-error-dark: 178 35 35;
189
189
  --os-color-error-light: 242 119 119;
190
190
  --os-color-error-alertBg: 92 26 26;
191
- --os-color-error-contrast: 255 255 255;
191
+ --os-color-error-contrast: 0 0 0;
192
192
  --os-color-error-fill: 231 76 76;
193
193
  --os-color-error-onFill: 0 0 0;
194
194
  --os-color-error-text: 242 119 119;
@@ -18,16 +18,16 @@
18
18
  --os-color-secondary-main: 110 122 90;
19
19
  --os-color-secondary-dark: 93 104 73;
20
20
  --os-color-secondary-light: 130 141 107;
21
- --os-color-secondary-contrast: 231 236 218;
21
+ --os-color-secondary-contrast: 255 255 255;
22
22
  --os-color-error-main: 211 47 47;
23
- --os-color-error-dark: 178 35 35;
23
+ --os-color-error-dark: 168 33 33;
24
24
  --os-color-error-light: 242 119 119;
25
25
  --os-color-error-alertBg: 242 196 196;
26
26
  --os-color-error-contrast: 255 255 255;
27
- --os-color-error-fill: 178 35 35;
27
+ --os-color-error-fill: 168 33 33;
28
28
  --os-color-error-onFill: 255 255 255;
29
- --os-color-error-text: 178 35 35;
30
- --os-color-error-textHover: 178 35 35;
29
+ --os-color-error-text: 168 33 33;
30
+ --os-color-error-textHover: 168 33 33;
31
31
  --os-color-error-tint: 242 119 119;
32
32
  --os-color-warning-main: 239 108 0;
33
33
  --os-color-warning-dark: 168 70 0;
@@ -100,12 +100,12 @@
100
100
  --os-color-secondary-main: 110 122 90;
101
101
  --os-color-secondary-dark: 93 104 73;
102
102
  --os-color-secondary-light: 130 141 107;
103
- --os-color-secondary-contrast: 217 229 199;
103
+ --os-color-secondary-contrast: 255 255 255;
104
104
  --os-color-error-main: 231 76 76;
105
105
  --os-color-error-dark: 178 35 35;
106
106
  --os-color-error-light: 242 119 119;
107
107
  --os-color-error-alertBg: 92 26 26;
108
- --os-color-error-contrast: 255 255 255;
108
+ --os-color-error-contrast: 0 0 0;
109
109
  --os-color-error-fill: 231 76 76;
110
110
  --os-color-error-onFill: 0 0 0;
111
111
  --os-color-error-text: 242 119 119;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oneslash-design-system",
3
3
  "description": "A design system for the Oneslash projects",
4
- "version": "2.0.1",
4
+ "version": "2.0.3",
5
5
  "private": false,
6
6
  "main": "./dist/index.js",
7
7
  "types": "./dist/index.d.ts",