@cas-smartdesign/button 7.0.1 → 7.1.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cas-smartdesign/button",
3
- "version": "7.0.1",
3
+ "version": "7.1.0",
4
4
  "description": "A button element which encloses the look and feel of the smartdesign button",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "files": [
@@ -17,12 +17,12 @@
17
17
  "registry": "https://registry.npmjs.org/"
18
18
  },
19
19
  "dependencies": {
20
- "@cas-smartdesign/image-embed": "^1.0.1",
20
+ "@cas-smartdesign/image-embed": "^1.0.2",
21
21
  "@cas-smartdesign/element-base": "^6.0.0"
22
22
  },
23
23
  "devDependencies": {
24
- "@cas-smartdesign/element-preview": "^1.1.0",
25
- "@cas-smartdesign/license-generator": "^1.10.0"
24
+ "@cas-smartdesign/license-generator": "^1.10.0",
25
+ "@cas-smartdesign/element-preview": "^1.1.0"
26
26
  },
27
27
  "peerDependencies": {
28
28
  "@cas-smartdesign/design-tokens": "^3.0.1"
package/readme.md CHANGED
@@ -17,7 +17,7 @@ For a web app / web widget, refer to the official documentation about design tok
17
17
  - `type`: string
18
18
  - Can be set to either `submit` or `reset` to make the button act like a HTML form button.
19
19
  - `variant`: string
20
- - Defines the visual style of the button. One of `primary`, `outline`, `standard`, `ghost`, `outline-danger`, `ghost-danger`, `selection` or `custom`. Defaults to `standard` when unset or set to an unknown value.
20
+ - Defines the visual style of the button. One of `primary`, `outline`, `standard`, `ghost`, `outline-danger`, `ghost-danger`, `selection`, `custom` or `contrast`. Defaults to `standard` when unset or set to an unknown value.
21
21
  - `aria-pressed`: boolean
22
22
  - Marks a `selection` button as selected (standard toggle-button semantics). When the variant is set to `selection` and the attribute is absent, the button initializes it to `false` so assistive tools announce it as a toggle; the consumer flips it to `true`/`false`.
23
23
 
@@ -26,7 +26,7 @@ For a web app / web widget, refer to the official documentation about design tok
26
26
  - `disabled`: boolean
27
27
  - Makes the button looks like it is disabled & also prevents click events but used with a classname so mouse events are still triggered thus allowing for example tooltip usage in all browsers.
28
28
  - `variant`: ButtonVariant
29
- - Gets or sets the button's visual style (`primary`, `outline`, `standard`, `ghost`, `outline-danger`, `ghost-danger`, `selection` or `custom`). Reading it returns `standard` when the `variant` attribute is missing or invalid.
29
+ - Gets or sets the button's visual style (`primary`, `outline`, `standard`, `ghost`, `outline-danger`, `ghost-danger`, `selection`, `custom` or `contrast`). Reading it returns `standard` when the `variant` attribute is missing or invalid.
30
30
 
31
31
  ## CSS Custom Properties
32
32
 
@@ -45,6 +45,12 @@ For the `custom` variant you only need to set the two rest colors — `--sd-butt
45
45
 
46
46
  Mind the color contrast when relying on the derived states: because the background darkens while the text color is kept, a `--sd-button-color` that contrasts well against the rest background may fall below the required contrast ratio against the darker hover/pressed background. If the derived states do not meet your contrast requirements, set `--sd-button-color-hover` and `--sd-button-color-pressed` (and the matching background properties) explicitly.
47
47
 
48
+ The `contrast` variant is transparent at rest and derives its foreground automatically from the surface it sits on. Point `--sd-button-contrast-source` at the color behind the button (it defaults to the themed page background `--color-bg-default`, so it already follows the light/dark theme). The derived color is exposed as `--sd-button-contrast-color` and kept across every state — the foreground never changes.
49
+
50
+ - `--sd-button-contrast-source`
51
+ - (`contrast` variant) The surface color behind the button, used to derive a legible foreground and the hover/pressed shades. Defaults to `--color-bg-default`.
52
+ - `--sd-button-contrast-color`
53
+ - (`contrast` variant) The derived foreground color (computed from `--sd-button-contrast-source`). Used for the text/icon color in every state. Override to pin the foreground.
48
54
  - `--sd-button-background-color`
49
55
  - Background color in the default (rest) state.
50
56
  - `--sd-button-color`
package/scss/_button.scss CHANGED
@@ -19,6 +19,7 @@
19
19
  box-sizing: border-box;
20
20
  vertical-align: middle;
21
21
  min-height: 36px;
22
+ height: min-content;
22
23
  padding: var(--spacing-x3, 6px) var(--spacing-x4, 8px);
23
24
  border-radius: var(--radius-s, 4px);
24
25
  cursor: pointer;
package/scss/_config.scss CHANGED
@@ -4,6 +4,33 @@
4
4
  // and the public mixins (_button.scss). Keep selector-agnostic: declarations only,
5
5
  // callers provide the selector (`:host(...)` for the component, `&` for consumers).
6
6
 
7
+ // Returns a foreground color that stays legible on `$variable` (a color or a
8
+ // custom property holding one): near-black on light backgrounds, white on dark
9
+ // ones. It reads the source's relative-color `y` (XYZ luminance) to pick each
10
+ // channel, so the whole expression must reach the browser verbatim — it is
11
+ // interpolated as an unquoted string so Sass does not try to evaluate the CSS
12
+ // round()/min()/max() or the `y` keyword at compile time.
13
+ @function get-contrast-color($variable) {
14
+ // 0.18 is the geometric mean between black and white in XYZ color space.
15
+ $mid-gray: 0.18;
16
+ $lightening-factor: 17.6%;
17
+ $channel: "round(up, min(1, max(0, #{$mid-gray} - y)), 1)";
18
+ @return #{"color-mix(in oklab, color(from #{$variable} xyz #{$channel} #{$channel} #{$channel}), #fff #{$lightening-factor})"};
19
+ }
20
+
21
+ // Hover/pressed fill for the contrast variant: a lighter-or-darker shade of the
22
+ // surface, made by stepping its OKLab lightness by a fixed perceptual amount
23
+ // (`$shift`) toward whichever extreme reads as higher contrast. A constant
24
+ // lightness step beats a fixed percentage mix toward the foreground: a vivid
25
+ // mid-toned surface like #e2001a sits close to its near-white foreground, so a
26
+ // 10% mix barely shows, whereas a fixed L step stays equally visible on pale,
27
+ // vivid and dark surfaces alike. `a`/`b` are kept, so it is the same hue at a
28
+ // new lightness. Interpolated as a string so Sass passes the relative color,
29
+ // sign() and calc() through verbatim.
30
+ @function get-contrast-fill($variable, $shift) {
31
+ @return #{"oklab(from #{$variable} calc(l + sign(0.5 - l) * #{$shift}) a b)"};
32
+ }
33
+
7
34
  // Neutral (standard variant) colors per interactive state. These are the fallbacks
8
35
  // the engine paints with when no variant overrides the corresponding --sd-button-*.
9
36
  $neutral: (
@@ -31,6 +58,11 @@ $neutral: (
31
58
  $_custom-bg: var(--sd-button-background-color, #{map.get(map.get($neutral, "base"), "bg")});
32
59
  $_custom-fg: var(--sd-button-color, #{map.get(map.get($neutral, "base"), "fg")});
33
60
 
61
+ // Contrast variant source: the surface color the button sits on. The variant
62
+ // derives a legible foreground from it, defaulting to the themed page background
63
+ // so it adapts to light/dark themes without any consumer override.
64
+ $_contrast-source: var(--sd-button-contrast-source, var(--color-bg-default, #ffffff));
65
+
34
66
  // Per-variant --sd-button-* values. Adding a variant is a single map entry.
35
67
  $variants: (
36
68
  "primary": (
@@ -104,11 +136,29 @@ $variants: (
104
136
  // and --sd-button-color, and hover/pressed are derived from them automatically.
105
137
  // Any state can still be pinned by overriding the matching --sd-button-* property.
106
138
  "custom": (
107
- "background-color-hover": color-mix(in oklab, $_custom-bg, var(--color-fg-default, #111111) 12%),
139
+ "background-color-hover": color-mix(in oklab, $_custom-bg, var(--color-fg-default, #111111) 10%),
108
140
  "color-hover": $_custom-fg,
109
- "background-color-pressed": color-mix(in oklab, $_custom-bg, var(--color-fg-default, #111111) 22%),
141
+ "background-color-pressed": color-mix(in oklab, $_custom-bg, var(--color-fg-default, #111111) 20%),
110
142
  "color-pressed": $_custom-fg,
111
143
  ),
144
+ // Transparent at rest with a foreground auto-derived from the surface behind
145
+ // the button (--sd-button-contrast-source) so it stays legible on light or
146
+ // dark backgrounds. The derived color is computed once into the intermediate
147
+ // --sd-button-contrast-color and kept across every state (the foreground never
148
+ // changes). Hover/pressed fill the background with a lighter-or-darker shade of
149
+ // the surface via a perceptually-uniform OKLab lightness step, so the feedback
150
+ // reads equally on pale, vivid and dark surfaces. Pin the foreground by
151
+ // overriding --sd-button-contrast-color, or any --sd-button-* for one state.
152
+ "contrast": (
153
+ "contrast-color": get-contrast-color($_contrast-source),
154
+ "background-color": transparent,
155
+ "color": var(--sd-button-contrast-color),
156
+ "background-color-hover": get-contrast-fill($_contrast-source, 0.1),
157
+ "color-hover": var(--sd-button-contrast-color),
158
+ "background-color-pressed": get-contrast-fill($_contrast-source, 0.2),
159
+ "color-pressed": var(--sd-button-contrast-color),
160
+ "background-color-disabled": transparent,
161
+ ),
112
162
  );
113
163
 
114
164
  // Paint one interactive state: reads the public --sd-button-* override with the