@sproutsocial/seeds-react-theme 4.3.0 → 4.4.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.
Files changed (37) hide show
  1. package/README.md +21 -14
  2. package/commonjs/builders/buildCSS.js +5 -0
  3. package/commonjs/builders/buildTailwindV4.js +32 -14
  4. package/commonjs/builders/buildThemeSCSS.js +56 -0
  5. package/commonjs/builders/utils.js +35 -18
  6. package/commonjs/dark/theme.js +9 -2
  7. package/commonjs/light/theme.js +13 -5
  8. package/dist/tailwind-preset.css +5 -0
  9. package/dist/theme-all.css +14 -2
  10. package/dist/theme-dark.css +7 -1
  11. package/dist/theme.css +7 -1
  12. package/dist/themes/dark/_themed.scss +7 -3
  13. package/dist/themes/dark/theme.scss +10 -4
  14. package/dist/themes/extendedThemes/sproutTheme/dark/_themed.scss +7 -3
  15. package/dist/themes/extendedThemes/sproutTheme/dark/theme.scss +5 -2
  16. package/dist/themes/extendedThemes/sproutTheme/light/_themed.scss +7 -3
  17. package/dist/themes/extendedThemes/sproutTheme/light/theme.scss +5 -2
  18. package/dist/themes/light/_themed.scss +7 -3
  19. package/dist/themes/light/theme.scss +10 -4
  20. package/dist/types/builders/buildCSS.d.ts.map +1 -1
  21. package/dist/types/builders/buildTailwindV4.d.ts.map +1 -1
  22. package/dist/types/builders/buildThemeSCSS.d.ts +2 -0
  23. package/dist/types/builders/buildThemeSCSS.d.ts.map +1 -0
  24. package/dist/types/builders/utils.d.ts +4 -0
  25. package/dist/types/builders/utils.d.ts.map +1 -1
  26. package/dist/types/dark/theme.d.ts +6 -0
  27. package/dist/types/dark/theme.d.ts.map +1 -1
  28. package/dist/types/light/theme.d.ts +6 -0
  29. package/dist/types/light/theme.d.ts.map +1 -1
  30. package/lib/builders/buildCSS.js +6 -1
  31. package/lib/builders/buildTailwindV4.js +32 -14
  32. package/lib/builders/buildThemeSCSS.js +50 -0
  33. package/lib/builders/utils.js +34 -18
  34. package/lib/dark/theme.js +9 -2
  35. package/lib/light/theme.js +13 -5
  36. package/package.json +10 -5
  37. package/dist/themes/types/_themed.scss +0 -126
package/README.md CHANGED
@@ -26,8 +26,8 @@ yarn add @sproutsocial/seeds-react-theme
26
26
  ### React (styled-components)
27
27
 
28
28
  ```jsx
29
- import { ThemeProvider } from 'styled-components';
30
- import theme from '@sproutsocial/seeds-react-theme';
29
+ import { ThemeProvider } from "styled-components";
30
+ import theme from "@sproutsocial/seeds-react-theme";
31
31
 
32
32
  function App() {
33
33
  return (
@@ -47,11 +47,9 @@ See [MULTI_FRAMEWORK_GUIDE.md](./MULTI_FRAMEWORK_GUIDE.md) for complete document
47
47
  ```javascript
48
48
  // tailwind.config.js
49
49
  module.exports = {
50
- presets: [
51
- require('@sproutsocial/seeds-react-theme/dist/tailwind-preset'),
52
- ],
53
- content: ['./src/**/*.{js,jsx,ts,tsx}'],
54
- }
50
+ presets: [require("@sproutsocial/seeds-react-theme/dist/tailwind-preset")],
51
+ content: ["./src/**/*.{js,jsx,ts,tsx}"],
52
+ };
55
53
  ```
56
54
 
57
55
  ```jsx
@@ -63,14 +61,19 @@ module.exports = {
63
61
  ### CSS Custom Properties
64
62
 
65
63
  ```html
66
- <link rel="stylesheet" href="node_modules/@sproutsocial/seeds-react-theme/dist/theme.css">
64
+ <link
65
+ rel="stylesheet"
66
+ href="node_modules/@sproutsocial/seeds-react-theme/dist/theme.css"
67
+ />
67
68
 
68
- <button style="
69
+ <button
70
+ style="
69
71
  background: var(--color-button-primary-bg-base);
70
72
  color: var(--color-button-primary-text-base);
71
73
  padding: var(--space-400);
72
74
  border-radius: var(--radius-500);
73
- ">
75
+ "
76
+ >
74
77
  Primary Button
75
78
  </button>
76
79
  ```
@@ -109,9 +112,9 @@ Use the dark mode preset:
109
112
  ```javascript
110
113
  module.exports = {
111
114
  presets: [
112
- require('@sproutsocial/seeds-react-theme/dist/tailwind-preset-dark'),
115
+ require("@sproutsocial/seeds-react-theme/dist/tailwind-preset-dark"),
113
116
  ],
114
- }
117
+ };
115
118
  ```
116
119
 
117
120
  ### CSS Variables
@@ -128,15 +131,16 @@ Toggle with JavaScript:
128
131
 
129
132
  ```javascript
130
133
  // Enable dark mode
131
- document.documentElement.setAttribute('data-theme', 'dark');
134
+ document.documentElement.setAttribute("data-theme", "dark");
132
135
 
133
136
  // Disable dark mode
134
- document.documentElement.removeAttribute('data-theme');
137
+ document.documentElement.removeAttribute("data-theme");
135
138
  ```
136
139
 
137
140
  ## Available Tokens
138
141
 
139
142
  ### Colors
143
+
140
144
  - Button colors (primary, secondary, destructive, etc.)
141
145
  - Text colors (headline, body, subtext, inverse)
142
146
  - Link colors
@@ -145,14 +149,17 @@ document.documentElement.removeAttribute('data-theme');
145
149
  - Icon colors
146
150
 
147
151
  ### Spacing
152
+
148
153
  - `0`, `100`, `200`, `300`, `350`, `400`, `450`, `500`, `600`
149
154
 
150
155
  ### Typography
156
+
151
157
  - Font sizes and line heights (`100` - `1200`)
152
158
  - Font families
153
159
  - Font weights (normal, semibold, bold, extrabold)
154
160
 
155
161
  ### Other
162
+
156
163
  - Border radius values
157
164
  - Box shadows
158
165
  - Motion (easing, duration)
@@ -123,6 +123,11 @@ function generateCSSVariables(themeObj, mode) {
123
123
  variables.push.apply(variables, _toConsumableArray(objectToCSSVariables(radii, "radius")));
124
124
  console.log(" - Mapped ".concat(Object.keys(radii).length, " border radius values"));
125
125
 
126
+ // Border width
127
+ var borderWidths = (0, _utils.flattenBorderWidths)(themeObj.borderWidths);
128
+ variables.push.apply(variables, _toConsumableArray(objectToCSSVariables(borderWidths, "border-width")));
129
+ console.log(" - Mapped ".concat(Object.keys(borderWidths).length, " border width values"));
130
+
126
131
  // Shadows
127
132
  var shadows = (0, _utils.flattenShadows)(themeObj.shadows);
128
133
  variables.push.apply(variables, _toConsumableArray(objectToCSSVariables(shadows, "shadow")));
@@ -42,7 +42,7 @@ function buildTailwindV4Preset() {
42
42
  }
43
43
  function _buildTailwindV4Preset() {
44
44
  _buildTailwindV4Preset = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
45
- var distDir, lines, spacingMap, _i, _Object$entries, _Object$entries$_i, key, value, radiusMap, _i2, _Object$entries2, _Object$entries2$_i, _key, _value, typographyScales, _i3, _typographyScales, scale, _key2, val, buttonColors, _i4, _Object$entries3, _Object$entries3$_i, _key3, _value2, semanticColors, _i5, _Object$entries4, _Object$entries4$_i, _key4, _value3, darkButtonColors, _i6, _Object$entries5, _Object$entries5$_i, _key5, _value4, css, outPath;
45
+ var distDir, lines, spacingMap, _i, _Object$entries, _Object$entries$_i, key, value, radiusMap, _i2, _Object$entries2, _Object$entries2$_i, _key, _value, borderWidthMap, _i3, _Object$entries3, _Object$entries3$_i, _key2, _value2, typographyScales, _i4, _typographyScales, scale, _key3, val, buttonColors, _i5, _Object$entries4, _Object$entries4$_i, _key4, _value3, semanticColors, _i6, _Object$entries5, _Object$entries5$_i, _key5, _value4, darkButtonColors, _i7, _Object$entries6, _Object$entries6$_i, _key6, _value5, css, outPath;
46
46
  return _regenerator().w(function (_context) {
47
47
  while (1) switch (_context.n) {
48
48
  case 0:
@@ -99,16 +99,34 @@ function _buildTailwindV4Preset() {
99
99
  console.log(" - Mapped ".concat(Object.keys(radiusMap).length, " border radius tokens"));
100
100
  lines.push("");
101
101
 
102
+ // -------------------------------------------------------------------------
103
+ // Border width — from @sproutsocial/seeds-border
104
+ // Seeds' own `border-w-{key}` utility (not Tailwind's numeric border-<n>
105
+ // scale) — see seeds-react-system-props/src/scales.ts SCALE_PROPS.borderWidth
106
+ // -------------------------------------------------------------------------
107
+ lines.push(" /* Border width — from @sproutsocial/seeds-border */");
108
+ borderWidthMap = {
109
+ 500: BORDER.BORDER_WIDTH_500,
110
+ 600: BORDER.BORDER_WIDTH_600,
111
+ 700: BORDER.BORDER_WIDTH_700
112
+ };
113
+ for (_i3 = 0, _Object$entries3 = Object.entries(borderWidthMap); _i3 < _Object$entries3.length; _i3++) {
114
+ _Object$entries3$_i = _slicedToArray(_Object$entries3[_i3], 2), _key2 = _Object$entries3$_i[0], _value2 = _Object$entries3$_i[1];
115
+ lines.push(" --border-width-".concat(_key2, ": ").concat(_value2, ";"));
116
+ }
117
+ console.log(" - Mapped ".concat(Object.keys(borderWidthMap).length, " border width tokens"));
118
+ lines.push("");
119
+
102
120
  // -------------------------------------------------------------------------
103
121
  // Font size — from @sproutsocial/seeds-typography
104
122
  // Tailwind v4: --text-{key}--font-size + --text-{key}--line-height → text-{key}
105
123
  // -------------------------------------------------------------------------
106
124
  lines.push(" /* Font size — from @sproutsocial/seeds-typography */");
107
125
  typographyScales = [100, 200, 300, 400, 500, 600, 700];
108
- for (_i3 = 0, _typographyScales = typographyScales; _i3 < _typographyScales.length; _i3++) {
109
- scale = _typographyScales[_i3];
110
- _key2 = "TYPOGRAPHY_SIZE_".concat(scale);
111
- val = TYPOGRAPHY[_key2];
126
+ for (_i4 = 0, _typographyScales = typographyScales; _i4 < _typographyScales.length; _i4++) {
127
+ scale = _typographyScales[_i4];
128
+ _key3 = "TYPOGRAPHY_SIZE_".concat(scale);
129
+ val = TYPOGRAPHY[_key3];
112
130
  if (val && val.fontSize && val.lineHeight) {
113
131
  // Tailwind v4 uses --text-*--font-size and --text-*--line-height for
114
132
  // the two-value tuple equivalent
@@ -154,9 +172,9 @@ function _buildTailwindV4Preset() {
154
172
  "color-button-placeholder-text-hover": COLORS.COLOR_BLUE_800,
155
173
  "color-button-placeholder-border-base": COLORS.COLOR_NEUTRAL_500
156
174
  };
157
- for (_i4 = 0, _Object$entries3 = Object.entries(buttonColors); _i4 < _Object$entries3.length; _i4++) {
158
- _Object$entries3$_i = _slicedToArray(_Object$entries3[_i4], 2), _key3 = _Object$entries3$_i[0], _value2 = _Object$entries3$_i[1];
159
- lines.push(" --".concat(_key3, ": ").concat(_value2, ";"));
175
+ for (_i5 = 0, _Object$entries4 = Object.entries(buttonColors); _i5 < _Object$entries4.length; _i5++) {
176
+ _Object$entries4$_i = _slicedToArray(_Object$entries4[_i5], 2), _key4 = _Object$entries4$_i[0], _value3 = _Object$entries4$_i[1];
177
+ lines.push(" --".concat(_key4, ": ").concat(_value3, ";"));
160
178
  }
161
179
  console.log(" - Mapped ".concat(Object.keys(buttonColors).length, " button color tokens"));
162
180
  lines.push("");
@@ -186,9 +204,9 @@ function _buildTailwindV4Preset() {
186
204
  "color-form-border-selected": "var(--color-form-border-selected)",
187
205
  "color-form-placeholder-base": "var(--color-form-placeholder-base)"
188
206
  };
189
- for (_i5 = 0, _Object$entries4 = Object.entries(semanticColors); _i5 < _Object$entries4.length; _i5++) {
190
- _Object$entries4$_i = _slicedToArray(_Object$entries4[_i5], 2), _key4 = _Object$entries4$_i[0], _value3 = _Object$entries4$_i[1];
191
- lines.push(" --".concat(_key4, ": ").concat(_value3, ";"));
207
+ for (_i6 = 0, _Object$entries5 = Object.entries(semanticColors); _i6 < _Object$entries5.length; _i6++) {
208
+ _Object$entries5$_i = _slicedToArray(_Object$entries5[_i6], 2), _key5 = _Object$entries5$_i[0], _value4 = _Object$entries5$_i[1];
209
+ lines.push(" --".concat(_key5, ": ").concat(_value4, ";"));
192
210
  }
193
211
  console.log(" - Mapped ".concat(Object.keys(semanticColors).length, " semantic color tokens"));
194
212
 
@@ -217,9 +235,9 @@ function _buildTailwindV4Preset() {
217
235
  "color-button-placeholder-text-base-dark": COLORS.COLOR_BLUE_400,
218
236
  "color-button-placeholder-text-hover-dark": COLORS.COLOR_BLUE_300
219
237
  };
220
- for (_i6 = 0, _Object$entries5 = Object.entries(darkButtonColors); _i6 < _Object$entries5.length; _i6++) {
221
- _Object$entries5$_i = _slicedToArray(_Object$entries5[_i6], 2), _key5 = _Object$entries5$_i[0], _value4 = _Object$entries5$_i[1];
222
- lines.push(" --".concat(_key5, ": ").concat(_value4, ";"));
238
+ for (_i7 = 0, _Object$entries6 = Object.entries(darkButtonColors); _i7 < _Object$entries6.length; _i7++) {
239
+ _Object$entries6$_i = _slicedToArray(_Object$entries6[_i7], 2), _key6 = _Object$entries6$_i[0], _value5 = _Object$entries6$_i[1];
240
+ lines.push(" --".concat(_key6, ": ").concat(_value5, ";"));
223
241
  }
224
242
  console.log(" - Mapped ".concat(Object.keys(darkButtonColors).length, " dark mode button color tokens"));
225
243
  lines.push("}");
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.buildThemeSCSSFiles = void 0;
7
+ var _fs = _interopRequireDefault(require("fs"));
8
+ var _glob = require("glob");
9
+ var _child_process = require("child_process");
10
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
11
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i.return) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
12
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
13
+ function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
14
+ function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
15
+ //@ts-ignore
16
+ var execSyncHelper = function execSyncHelper(command, extraEnv) {
17
+ return (0, _child_process.execSync)(command, {
18
+ stdio: "inherit",
19
+ env: Object.assign({}, process.env, extraEnv)
20
+ });
21
+ };
22
+
23
+ // Generate theme.scss and add a copy of _themed.scss to /dist for each theme
24
+ var buildThemeSCSSFiles = exports.buildThemeSCSSFiles = /*#__PURE__*/function () {
25
+ var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
26
+ var themeFiles;
27
+ return _regenerator().w(function (_context) {
28
+ while (1) switch (_context.n) {
29
+ case 0:
30
+ console.log("Building theme stylesheets");
31
+
32
+ // "types" excluded: src/types/theme.ts is a type-only file that happens to
33
+ // share the "theme" basename with the real theme data modules, and its
34
+ // compiled output has no runtime keys for json-to-scss to convert.
35
+ themeFiles = (0, _glob.sync)("./commonjs/**/theme.js", {
36
+ ignore: "commonjs/types/**"
37
+ });
38
+ themeFiles.forEach(function (fileName) {
39
+ var themeDistDirectory = fileName.replace("commonjs", "dist/themes").replace("/theme.js", "");
40
+ if (!_fs.default.existsSync(themeDistDirectory)) {
41
+ _fs.default.mkdirSync(themeDistDirectory, {
42
+ recursive: true
43
+ });
44
+ }
45
+ execSyncHelper("json-to-scss '".concat(fileName, "' '").concat(themeDistDirectory, "/theme.scss' --k=\"dq\""));
46
+ execSyncHelper("cp './src/utils/_themed.scss' '".concat(themeDistDirectory, "/_themed.scss'"));
47
+ });
48
+ case 1:
49
+ return _context.a(2);
50
+ }
51
+ }, _callee);
52
+ }));
53
+ return function buildThemeSCSSFiles() {
54
+ return _ref.apply(this, arguments);
55
+ };
56
+ }();
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.filterComplexColors = filterComplexColors;
7
+ exports.flattenBorderWidths = flattenBorderWidths;
7
8
  exports.flattenColors = flattenColors;
8
9
  exports.flattenDuration = flattenDuration;
9
10
  exports.flattenEasing = flattenEasing;
@@ -134,11 +135,11 @@ function flattenRadii(radii) {
134
135
  }
135
136
 
136
137
  /**
137
- * Flatten shadows
138
+ * Flatten border widths
138
139
  */
139
- function flattenShadows(shadows) {
140
+ function flattenBorderWidths(borderWidths) {
140
141
  var flattened = {};
141
- for (var _i5 = 0, _Object$entries5 = Object.entries(shadows); _i5 < _Object$entries5.length; _i5++) {
142
+ for (var _i5 = 0, _Object$entries5 = Object.entries(borderWidths); _i5 < _Object$entries5.length; _i5++) {
142
143
  var _Object$entries5$_i = _slicedToArray(_Object$entries5[_i5], 2),
143
144
  key = _Object$entries5$_i[0],
144
145
  value = _Object$entries5$_i[1];
@@ -150,15 +151,15 @@ function flattenShadows(shadows) {
150
151
  }
151
152
 
152
153
  /**
153
- * Flatten font weights
154
+ * Flatten shadows
154
155
  */
155
- function flattenFontWeights(fontWeights) {
156
+ function flattenShadows(shadows) {
156
157
  var flattened = {};
157
- for (var _i6 = 0, _Object$entries6 = Object.entries(fontWeights); _i6 < _Object$entries6.length; _i6++) {
158
+ for (var _i6 = 0, _Object$entries6 = Object.entries(shadows); _i6 < _Object$entries6.length; _i6++) {
158
159
  var _Object$entries6$_i = _slicedToArray(_Object$entries6[_i6], 2),
159
160
  key = _Object$entries6$_i[0],
160
161
  value = _Object$entries6$_i[1];
161
- if (typeof value === "string" || typeof value === "number") {
162
+ if (typeof value === "string") {
162
163
  flattened[key] = value;
163
164
  }
164
165
  }
@@ -166,15 +167,15 @@ function flattenFontWeights(fontWeights) {
166
167
  }
167
168
 
168
169
  /**
169
- * Flatten easing (transition timing functions)
170
+ * Flatten font weights
170
171
  */
171
- function flattenEasing(easing) {
172
+ function flattenFontWeights(fontWeights) {
172
173
  var flattened = {};
173
- for (var _i7 = 0, _Object$entries7 = Object.entries(easing); _i7 < _Object$entries7.length; _i7++) {
174
+ for (var _i7 = 0, _Object$entries7 = Object.entries(fontWeights); _i7 < _Object$entries7.length; _i7++) {
174
175
  var _Object$entries7$_i = _slicedToArray(_Object$entries7[_i7], 2),
175
176
  key = _Object$entries7$_i[0],
176
177
  value = _Object$entries7$_i[1];
177
- if (typeof value === "string") {
178
+ if (typeof value === "string" || typeof value === "number") {
178
179
  flattened[key] = value;
179
180
  }
180
181
  }
@@ -182,11 +183,11 @@ function flattenEasing(easing) {
182
183
  }
183
184
 
184
185
  /**
185
- * Flatten duration (transition durations)
186
+ * Flatten easing (transition timing functions)
186
187
  */
187
- function flattenDuration(duration) {
188
+ function flattenEasing(easing) {
188
189
  var flattened = {};
189
- for (var _i8 = 0, _Object$entries8 = Object.entries(duration); _i8 < _Object$entries8.length; _i8++) {
190
+ for (var _i8 = 0, _Object$entries8 = Object.entries(easing); _i8 < _Object$entries8.length; _i8++) {
190
191
  var _Object$entries8$_i = _slicedToArray(_Object$entries8[_i8], 2),
191
192
  key = _Object$entries8$_i[0],
192
193
  value = _Object$entries8$_i[1];
@@ -197,6 +198,22 @@ function flattenDuration(duration) {
197
198
  return flattened;
198
199
  }
199
200
 
201
+ /**
202
+ * Flatten duration (transition durations)
203
+ */
204
+ function flattenDuration(duration) {
205
+ var flattened = {};
206
+ for (var _i9 = 0, _Object$entries9 = Object.entries(duration); _i9 < _Object$entries9.length; _i9++) {
207
+ var _Object$entries9$_i = _slicedToArray(_Object$entries9[_i9], 2),
208
+ key = _Object$entries9$_i[0],
209
+ value = _Object$entries9$_i[1];
210
+ if (typeof value === "string") {
211
+ flattened[key] = value;
212
+ }
213
+ }
214
+ return flattened;
215
+ }
216
+
200
217
  /**
201
218
  * Check if a value is a valid CSS color
202
219
  * Filters out complex values like color-mix() which may not work everywhere
@@ -210,10 +227,10 @@ function isSimpleColor(value) {
210
227
  */
211
228
  function filterComplexColors(colors) {
212
229
  var filtered = {};
213
- for (var _i9 = 0, _Object$entries9 = Object.entries(colors); _i9 < _Object$entries9.length; _i9++) {
214
- var _Object$entries9$_i = _slicedToArray(_Object$entries9[_i9], 2),
215
- key = _Object$entries9$_i[0],
216
- value = _Object$entries9$_i[1];
230
+ for (var _i0 = 0, _Object$entries0 = Object.entries(colors); _i0 < _Object$entries0.length; _i0++) {
231
+ var _Object$entries0$_i = _slicedToArray(_Object$entries0[_i0], 2),
232
+ key = _Object$entries0$_i[0],
233
+ value = _Object$entries0$_i[1];
217
234
  if (isSimpleColor(value)) {
218
235
  filtered[key] = value;
219
236
  } else {
@@ -62,7 +62,9 @@ var colors = exports.colors = _objectSpread(_objectSpread({}, _theme.default.col
62
62
  neutral_sentiment: _seedsColor.default.COLOR_NEUTRAL_300,
63
63
  // 20% AI gradient tint over the dark container surface. Same token-driven
64
64
  // value as light mode; the referenced tokens flip per theme.
65
- ai_generated: "var(--color-gradient-ai-subtle), var(--color-container-bg-base)"
65
+ // The comma-separated composed value lives in _themed.scss (see comment
66
+ // there) since a literal comma here breaks SCSS map parsing.
67
+ ai_generated: "var(--color-container-bg-ai-generated)"
66
68
  },
67
69
  border: {
68
70
  base: _seedsColor.default.COLOR_NEUTRAL_1100,
@@ -94,7 +96,12 @@ var colors = exports.colors = _objectSpread(_objectSpread({}, _theme.default.col
94
96
  // contrast against the dark surface (Figma Sprout Variables, "Trellis" dark).
95
97
  gradient: {
96
98
  ai: "radial-gradient(circle at bottom left, #679eff 0%, #b984ff 61%, #f282f5 100%)",
97
- "ai-subtle": "radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%)"
99
+ "ai-subtle": "radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%)",
100
+ // Discrete stops for SVG paint servers — see the light theme for why these
101
+ // exist alongside the composed gradient strings.
102
+ "ai-stop-1": "#679eff",
103
+ "ai-stop-2": "#b984ff",
104
+ "ai-stop-3": "#f282f5"
98
105
  },
99
106
  button: {
100
107
  primary: {
@@ -68,10 +68,9 @@ var colors = exports.colors = _objectSpread(_objectSpread({
68
68
  negative_sentiment: _seedsColor.default.COLOR_RED_500,
69
69
  neutral_sentiment: _seedsColor.default.COLOR_NEUTRAL_300,
70
70
  // 20% AI gradient tint composited over the themed container surface.
71
- // Driven entirely by the ai-subtle + container-bg tokens so it adapts to
72
- // light/dark automatically (was previously a hardcoded, light-only value
73
- // injected by seeds-react-theme-provider).
74
- ai_generated: "var(--color-gradient-ai-subtle), var(--color-container-bg-base)"
71
+ // The comma-separated composed value lives in _themed.scss (see comment
72
+ // there) since a literal comma here breaks SCSS map parsing.
73
+ ai_generated: "var(--color-container-bg-ai-generated)"
75
74
  },
76
75
  border: {
77
76
  base: _seedsColor.default.COLOR_NEUTRAL_200,
@@ -106,7 +105,16 @@ var colors = exports.colors = _objectSpread(_objectSpread({
106
105
  ai: "radial-gradient(circle at bottom left, #205bc3 0%, #9747ff 61%, #f282f5 100%)",
107
106
  // 20% tint — AI secondary (composited over a white base in CSS).
108
107
  // Kebab key so it flattens to --color-gradient-ai-subtle.
109
- "ai-subtle": "radial-gradient(circle at bottom left, color-mix(in srgb, #205bc3, transparent 80%) 0%, color-mix(in srgb, #9747ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%)"
108
+ "ai-subtle": "radial-gradient(circle at bottom left, color-mix(in srgb, #205bc3, transparent 80%) 0%, color-mix(in srgb, #9747ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%)",
109
+ // The same three stops as discrete colors, flattening to
110
+ // --color-gradient-ai-stop-{1,2,3}. SVG needs a real <radialGradient> with
111
+ // separate <stop> elements to use as a paint server, and a CSS
112
+ // radial-gradient() string can't be decomposed back into stops. Consumed by
113
+ // seeds-react-icon's gradient defs (see icon.css) so gradient-filled icons
114
+ // pick up dark mode through the usual .dark variable swap.
115
+ "ai-stop-1": "#205bc3",
116
+ "ai-stop-2": "#9747ff",
117
+ "ai-stop-3": "#f282f5"
110
118
  },
111
119
  button: {
112
120
  primary: {
@@ -32,6 +32,11 @@
32
32
  --radius-inner: 4px;
33
33
  --radius-outer: 8px;
34
34
 
35
+ /* Border width — from @sproutsocial/seeds-border */
36
+ --border-width-500: 1px;
37
+ --border-width-600: 2px;
38
+ --border-width-700: 3px;
39
+
35
40
  /* Font size — from @sproutsocial/seeds-typography */
36
41
  --text-100--font-size: 11px;
37
42
  --text-100--line-height: 18.666666666666668px;
@@ -27,7 +27,7 @@
27
27
  --color-container-bg-positive_sentiment: #3876e3;
28
28
  --color-container-bg-negative_sentiment: #f76054;
29
29
  --color-container-bg-neutral_sentiment: #c8cccc;
30
- --color-container-bg-ai_generated: var(--color-gradient-ai-subtle), var(--color-container-bg-base);
30
+ --color-container-bg-ai_generated: var(--color-container-bg-ai-generated);
31
31
  --color-container-border-base: #dee1e1;
32
32
  --color-container-border-success: #59cb59;
33
33
  --color-container-border-warning: #ffbc00;
@@ -50,6 +50,9 @@
50
50
  --color-container-border-ai_generated: #6f5ed3;
51
51
  --color-gradient-ai: radial-gradient(circle at bottom left, #205bc3 0%, #9747ff 61%, #f282f5 100%);
52
52
  --color-gradient-ai-subtle: radial-gradient(circle at bottom left, color-mix(in srgb, #205bc3, transparent 80%) 0%, color-mix(in srgb, #9747ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%);
53
+ --color-gradient-ai-stop-1: #205bc3;
54
+ --color-gradient-ai-stop-2: #9747ff;
55
+ --color-gradient-ai-stop-3: #f282f5;
53
56
  --color-button-primary-bg-base: #205bc3;
54
57
  --color-button-primary-bg-hover: #1150aa;
55
58
  --color-button-primary-bg-active: #0c3f89;
@@ -468,6 +471,9 @@
468
471
  --radius-inner: 6px;
469
472
  --radius-outer: 8px;
470
473
  --radius-pill: 999999px;
474
+ --border-width-500: 1px;
475
+ --border-width-600: 2px;
476
+ --border-width-700: 3px;
471
477
  --shadow-low: 0px 2px 4px #2733333D;
472
478
  --shadow-medium: 0px 8px 16px #2733333D;
473
479
  --shadow-high: 0px 16px 32px #2733333D;
@@ -508,7 +514,7 @@
508
514
  --color-container-bg-positive_sentiment: #3876e3;
509
515
  --color-container-bg-negative_sentiment: #f76054;
510
516
  --color-container-bg-neutral_sentiment: #c8cccc;
511
- --color-container-bg-ai_generated: var(--color-gradient-ai-subtle), var(--color-container-bg-base);
517
+ --color-container-bg-ai_generated: var(--color-container-bg-ai-generated);
512
518
  --color-container-border-base: #040404;
513
519
  --color-container-border-success: #59cb59;
514
520
  --color-container-border-warning: #ffbc00;
@@ -531,6 +537,9 @@
531
537
  --color-container-border-ai_generated: #6f5ed3;
532
538
  --color-gradient-ai: radial-gradient(circle at bottom left, #679eff 0%, #b984ff 61%, #f282f5 100%);
533
539
  --color-gradient-ai-subtle: radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%);
540
+ --color-gradient-ai-stop-1: #679eff;
541
+ --color-gradient-ai-stop-2: #b984ff;
542
+ --color-gradient-ai-stop-3: #f282f5;
534
543
  --color-button-primary-bg-base: #679eff;
535
544
  --color-button-primary-bg-hover: #a1c2f8;
536
545
  --color-button-primary-bg-active: #c7dbf9;
@@ -949,6 +958,9 @@
949
958
  --radius-inner: 6px;
950
959
  --radius-outer: 8px;
951
960
  --radius-pill: 999999px;
961
+ --border-width-500: 1px;
962
+ --border-width-600: 2px;
963
+ --border-width-700: 3px;
952
964
  --shadow-low: 0px 2px 4px #040404FF;
953
965
  --shadow-medium: 0px 8px 16px #040404FF;
954
966
  --shadow-high: 0px 16px 32px #040404FF;
@@ -27,7 +27,7 @@
27
27
  --color-container-bg-positive_sentiment: #3876e3;
28
28
  --color-container-bg-negative_sentiment: #f76054;
29
29
  --color-container-bg-neutral_sentiment: #c8cccc;
30
- --color-container-bg-ai_generated: var(--color-gradient-ai-subtle), var(--color-container-bg-base);
30
+ --color-container-bg-ai_generated: var(--color-container-bg-ai-generated);
31
31
  --color-container-border-base: #040404;
32
32
  --color-container-border-success: #59cb59;
33
33
  --color-container-border-warning: #ffbc00;
@@ -50,6 +50,9 @@
50
50
  --color-container-border-ai_generated: #6f5ed3;
51
51
  --color-gradient-ai: radial-gradient(circle at bottom left, #679eff 0%, #b984ff 61%, #f282f5 100%);
52
52
  --color-gradient-ai-subtle: radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%);
53
+ --color-gradient-ai-stop-1: #679eff;
54
+ --color-gradient-ai-stop-2: #b984ff;
55
+ --color-gradient-ai-stop-3: #f282f5;
53
56
  --color-button-primary-bg-base: #679eff;
54
57
  --color-button-primary-bg-hover: #a1c2f8;
55
58
  --color-button-primary-bg-active: #c7dbf9;
@@ -468,6 +471,9 @@
468
471
  --radius-inner: 6px;
469
472
  --radius-outer: 8px;
470
473
  --radius-pill: 999999px;
474
+ --border-width-500: 1px;
475
+ --border-width-600: 2px;
476
+ --border-width-700: 3px;
471
477
  --shadow-low: 0px 2px 4px #040404FF;
472
478
  --shadow-medium: 0px 8px 16px #040404FF;
473
479
  --shadow-high: 0px 16px 32px #040404FF;
package/dist/theme.css CHANGED
@@ -27,7 +27,7 @@
27
27
  --color-container-bg-positive_sentiment: #3876e3;
28
28
  --color-container-bg-negative_sentiment: #f76054;
29
29
  --color-container-bg-neutral_sentiment: #c8cccc;
30
- --color-container-bg-ai_generated: var(--color-gradient-ai-subtle), var(--color-container-bg-base);
30
+ --color-container-bg-ai_generated: var(--color-container-bg-ai-generated);
31
31
  --color-container-border-base: #dee1e1;
32
32
  --color-container-border-success: #59cb59;
33
33
  --color-container-border-warning: #ffbc00;
@@ -50,6 +50,9 @@
50
50
  --color-container-border-ai_generated: #6f5ed3;
51
51
  --color-gradient-ai: radial-gradient(circle at bottom left, #205bc3 0%, #9747ff 61%, #f282f5 100%);
52
52
  --color-gradient-ai-subtle: radial-gradient(circle at bottom left, color-mix(in srgb, #205bc3, transparent 80%) 0%, color-mix(in srgb, #9747ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%);
53
+ --color-gradient-ai-stop-1: #205bc3;
54
+ --color-gradient-ai-stop-2: #9747ff;
55
+ --color-gradient-ai-stop-3: #f282f5;
53
56
  --color-button-primary-bg-base: #205bc3;
54
57
  --color-button-primary-bg-hover: #1150aa;
55
58
  --color-button-primary-bg-active: #0c3f89;
@@ -468,6 +471,9 @@
468
471
  --radius-inner: 6px;
469
472
  --radius-outer: 8px;
470
473
  --radius-pill: 999999px;
474
+ --border-width-500: 1px;
475
+ --border-width-600: 2px;
476
+ --border-width-700: 3px;
471
477
  --shadow-low: 0px 2px 4px #2733333D;
472
478
  --shadow-medium: 0px 8px 16px #2733333D;
473
479
  --shadow-high: 0px 16px 32px #2733333D;
@@ -7,10 +7,14 @@
7
7
  @import "./theme.scss";
8
8
 
9
9
  // CSS custom properties for values that can't be represented in SCSS maps.
10
- // radial-gradient + color-mix() breaks SCSS map parsing, so the theme object
11
- // holds a var() reference and the actual value is defined here.
10
+ // A comma-separated CSS value (e.g. a multi-layer background) breaks SCSS map
11
+ // parsing, since Sass reads the top-level comma as a second map value with no
12
+ // key. So the theme object holds a single var() reference, and the composed,
13
+ // comma-separated value is defined here instead, built from the other
14
+ // theme-driven vars so it stays correct for light and dark automatically.
12
15
  :root {
13
- --color-container-bg-ai-generated: radial-gradient(circle at bottom left, color-mix(in srgb, #205bc3, transparent 80%) 0%, color-mix(in srgb, #6f5ed3, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%), #f3f4f4;
16
+ --color-container-bg-ai-generated: var(--color-gradient-ai-subtle),
17
+ var(--color-container-bg-base);
14
18
  }
15
19
 
16
20
  // In the JS theme file, the theme object is exported as "default" (i.e., using "export default"),
@@ -31,7 +31,7 @@ $theme: (
31
31
  "positive_sentiment": #3876e3,
32
32
  "negative_sentiment": #f76054,
33
33
  "neutral_sentiment": #c8cccc,
34
- "ai_generated": var(--color-gradient-ai-subtle), var(--color-container-bg-base)
34
+ "ai_generated": var(--color-container-bg-ai-generated)
35
35
  ),
36
36
  "border": (
37
37
  "base": #040404,
@@ -60,7 +60,10 @@ $theme: (
60
60
  ),
61
61
  "gradient": (
62
62
  "ai": radial-gradient(circle at bottom left, #679eff 0%, #b984ff 61%, #f282f5 100%),
63
- "ai-subtle": radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%)
63
+ "ai-subtle": radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%),
64
+ "ai-stop-1": #679eff,
65
+ "ai-stop-2": #b984ff,
66
+ "ai-stop-3": #f282f5
64
67
  ),
65
68
  "button": (
66
69
  "primary": (
@@ -600,7 +603,7 @@ $theme: (
600
603
  "positive_sentiment": #3876e3,
601
604
  "negative_sentiment": #f76054,
602
605
  "neutral_sentiment": #c8cccc,
603
- "ai_generated": var(--color-gradient-ai-subtle), var(--color-container-bg-base)
606
+ "ai_generated": var(--color-container-bg-ai-generated)
604
607
  ),
605
608
  "border": (
606
609
  "base": #040404,
@@ -629,7 +632,10 @@ $theme: (
629
632
  ),
630
633
  "gradient": (
631
634
  "ai": radial-gradient(circle at bottom left, #679eff 0%, #b984ff 61%, #f282f5 100%),
632
- "ai-subtle": radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%)
635
+ "ai-subtle": radial-gradient(circle at bottom left, color-mix(in srgb, #679eff, transparent 80%) 0%, color-mix(in srgb, #b984ff, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%),
636
+ "ai-stop-1": #679eff,
637
+ "ai-stop-2": #b984ff,
638
+ "ai-stop-3": #f282f5
633
639
  ),
634
640
  "button": (
635
641
  "primary": (
@@ -7,10 +7,14 @@
7
7
  @import "./theme.scss";
8
8
 
9
9
  // CSS custom properties for values that can't be represented in SCSS maps.
10
- // radial-gradient + color-mix() breaks SCSS map parsing, so the theme object
11
- // holds a var() reference and the actual value is defined here.
10
+ // A comma-separated CSS value (e.g. a multi-layer background) breaks SCSS map
11
+ // parsing, since Sass reads the top-level comma as a second map value with no
12
+ // key. So the theme object holds a single var() reference, and the composed,
13
+ // comma-separated value is defined here instead, built from the other
14
+ // theme-driven vars so it stays correct for light and dark automatically.
12
15
  :root {
13
- --color-container-bg-ai-generated: radial-gradient(circle at bottom left, color-mix(in srgb, #205bc3, transparent 80%) 0%, color-mix(in srgb, #6f5ed3, transparent 80%) 61%, color-mix(in srgb, #f282f5, transparent 80%) 100%), #f3f4f4;
16
+ --color-container-bg-ai-generated: var(--color-gradient-ai-subtle),
17
+ var(--color-container-bg-base);
14
18
  }
15
19
 
16
20
  // In the JS theme file, the theme object is exported as "default" (i.e., using "export default"),