@keboola/tailwind-config 0.2.0 → 0.3.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/README.md CHANGED
@@ -15,7 +15,7 @@ branded) typically supplies its own tokens; this package is optional then.
15
15
  ```bash
16
16
  npm install -D @keboola/tailwind-config tailwindcss@^3
17
17
  # or
18
- yarn add -D @keboola/tailwind-config tailwindcss@^3
18
+ pnpm add -D @keboola/tailwind-config tailwindcss@^3
19
19
  ```
20
20
 
21
21
  ## Use
package/colors.ts CHANGED
@@ -1,3 +1,29 @@
1
+ // Keboola brand ramps. Historically these lived under `primary[100..900]` (green)
2
+ // and `secondary[100..900]` (blue); defined once here so the legacy `primary`/
3
+ // `secondary` aliases and the semantic-correct `green`/`blue` palettes can't drift.
4
+ const greenScale = {
5
+ 100: '#e0ffe0',
6
+ 200: '#baf5ba',
7
+ 300: '#93f593',
8
+ 400: '#51e051',
9
+ 500: '#1ec71e',
10
+ 600: '#1bb31b',
11
+ 700: '#189f18',
12
+ 800: '#158b15',
13
+ 900: '#0f630f',
14
+ };
15
+ const blueScale = {
16
+ 100: '#e0f0ff',
17
+ 200: '#c2e0ff',
18
+ 300: '#99ccff',
19
+ 400: '#5cadff',
20
+ 500: '#1f8fff',
21
+ 600: '#0975e0',
22
+ 700: '#075fb8',
23
+ 800: '#064a8f',
24
+ 900: '#043566',
25
+ };
26
+
1
27
  export default {
2
28
  inherit: 'inherit',
3
29
  transparent: 'rgba(255,255,255,0)',
@@ -15,7 +41,10 @@ export default {
15
41
  foreground: 'rgb(var(--color-foreground) / <alpha-value>)',
16
42
 
17
43
  // Raised container chrome (Modal/Card/Sheet). White in light, lifted off background in dark.
18
- surface: 'rgb(var(--color-surface) / <alpha-value>)',
44
+ card: {
45
+ DEFAULT: 'rgb(var(--color-card) / <alpha-value>)',
46
+ foreground: 'rgb(var(--color-card-foreground) / <alpha-value>)',
47
+ },
19
48
 
20
49
  popover: {
21
50
  DEFAULT: 'rgb(var(--color-popover) / <alpha-value>)',
@@ -34,12 +63,29 @@ export default {
34
63
  DEFAULT: 'rgb(var(--color-input) / <alpha-value>)',
35
64
  },
36
65
 
66
+ // Focus ring (brand blue).
67
+ ring: 'rgb(var(--color-ring) / <alpha-value>)',
68
+
69
+ // Categorical chart palette (brand-derived).
70
+ chart: {
71
+ 1: 'rgb(var(--color-chart-1) / <alpha-value>)',
72
+ 2: 'rgb(var(--color-chart-2) / <alpha-value>)',
73
+ 3: 'rgb(var(--color-chart-3) / <alpha-value>)',
74
+ 4: 'rgb(var(--color-chart-4) / <alpha-value>)',
75
+ 5: 'rgb(var(--color-chart-5) / <alpha-value>)',
76
+ },
77
+
37
78
  destructive: {
38
79
  DEFAULT: 'rgb(var(--color-destructive) / <alpha-value>)',
39
80
  foreground: 'rgb(var(--color-destructive-foreground) / <alpha-value>)',
40
81
  },
41
82
  success: {
42
83
  DEFAULT: 'rgb(var(--color-success) / <alpha-value>)',
84
+ foreground: 'rgb(var(--color-success-foreground) / <alpha-value>)',
85
+ },
86
+ info: {
87
+ DEFAULT: 'rgb(var(--color-info) / <alpha-value>)',
88
+ foreground: 'rgb(var(--color-info-foreground) / <alpha-value>)',
43
89
  },
44
90
 
45
91
  muted: {
@@ -74,28 +120,12 @@ export default {
74
120
  primary: {
75
121
  DEFAULT: 'rgb(var(--color-primary) / <alpha-value>)',
76
122
  foreground: 'rgb(var(--color-primary-foreground) / <alpha-value>)',
77
- 100: '#e0ffe0',
78
- 200: '#baf5ba',
79
- 300: '#93f593',
80
- 400: '#51e051',
81
- 500: '#1ec71e',
82
- 600: '#1bb31b',
83
- 700: '#189f18',
84
- 800: '#158b15',
85
- 900: '#0f630f',
123
+ ...greenScale,
86
124
  },
87
125
  secondary: {
88
- DEFAULT: '#E2E8F0',
89
- foreground: '#1E293B',
90
- 100: '#e0f0ff',
91
- 200: '#c2e0ff',
92
- 300: '#99ccff',
93
- 400: '#5cadff',
94
- 500: '#1f8fff',
95
- 600: '#0975e0',
96
- 700: '#075fb8',
97
- 800: '#064a8f',
98
- 900: '#043566',
126
+ DEFAULT: 'rgb(var(--color-secondary) / <alpha-value>)',
127
+ foreground: 'rgb(var(--color-secondary-foreground) / <alpha-value>)',
128
+ ...blueScale,
99
129
  },
100
130
  error: {
101
131
  100: '#ffe0e6',
@@ -110,6 +140,8 @@ export default {
110
140
  900: '#52000e',
111
141
  },
112
142
  warning: {
143
+ DEFAULT: 'rgb(var(--color-warning) / <alpha-value>)',
144
+ foreground: 'rgb(var(--color-warning-foreground) / <alpha-value>)',
113
145
  100: '#fff3e0',
114
146
  200: '#ffe7c2',
115
147
  300: '#ffd699',
@@ -176,4 +208,15 @@ export default {
176
208
  800: '#8A0F7D',
177
209
  900: '#5C0A54',
178
210
  },
211
+
212
+ // Semantic-correct names for the Keboola brand ramps that historically lived under
213
+ // `primary[100..900]` (green) and `secondary[100..900]` (blue) — fixed tints used
214
+ // directly regardless of brand, unlike `primary.DEFAULT` / `secondary.DEFAULT`
215
+ // (shadcn semantic, CSS-var driven). New code should use these; the `primary`/
216
+ // `secondary` ramps remain as aliases until their callsites are migrated (Step 2).
217
+ //
218
+ // Like the existing custom palettes (`cyan`/`teal`/`yellow`/`pink`/`purple`), these
219
+ // are `100..900` only and override Tailwind's same-named defaults.
220
+ green: { ...greenScale },
221
+ blue: { ...blueScale },
179
222
  };
package/index.js CHANGED
@@ -5,6 +5,7 @@ import { scopedPreflightStyles, isolateInsideOfContainer } from 'tailwindcss-sco
5
5
  import typographyPlugin from '@tailwindcss/typography';
6
6
  import containerQueriesPlugin from '@tailwindcss/container-queries';
7
7
  import { typography } from './typography';
8
+ import { scrollFadePlugin } from './scrollFade';
8
9
 
9
10
  /** @type {import('tailwindcss').Config} */
10
11
  export default {
@@ -174,5 +175,6 @@ export default {
174
175
  },
175
176
  });
176
177
  }),
178
+ scrollFadePlugin,
177
179
  ],
178
180
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keboola/tailwind-config",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "Shared Tailwind CSS v3 config for the Keboola UI platform — semantic color palette, plugins, and the `tw-` class prefix.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -14,6 +14,7 @@
14
14
  "index.js",
15
15
  "colors.ts",
16
16
  "typography.ts",
17
+ "scrollFade.ts",
17
18
  "README.md"
18
19
  ],
19
20
  "publishConfig": {
@@ -39,10 +40,6 @@
39
40
  "engines": {
40
41
  "node": ">=20"
41
42
  },
42
- "scripts": {
43
- "knip:check": "yarn --cwd ../.. exec knip --workspace packages/tailwind-config",
44
- "knip:fix": "yarn --cwd ../.. exec knip --workspace packages/tailwind-config --fix-type types,exports,files"
45
- },
46
43
  "peerDependencies": {
47
44
  "tailwindcss": "^3.4.0"
48
45
  },
@@ -51,5 +48,9 @@
51
48
  "@tailwindcss/typography": "^0.5.19",
52
49
  "tailwindcss-animate": "1.0.7",
53
50
  "tailwindcss-scoped-preflight": "3.5.2"
51
+ },
52
+ "scripts": {
53
+ "knip:check": "pnpm --dir ../.. exec knip --workspace packages/tailwind-config",
54
+ "knip:fix": "pnpm --dir ../.. exec knip --workspace packages/tailwind-config --fix-type types,exports,files"
54
55
  }
55
- }
56
+ }
package/scrollFade.ts ADDED
@@ -0,0 +1,53 @@
1
+ import plugin from 'tailwindcss/plugin';
2
+
3
+ // scroll-fade: fades scroll-container edges purely in CSS (mask-image + CSS scroll-driven
4
+ // animations, no JS). Mirrors shadcn/ui. https://ui.shadcn.com/docs/utils/scroll-fade
5
+ // Edge opacity is driven by two registered custom props (0 = faded, 1 = solid). With no
6
+ // overflow the scroll timeline is inactive, both hold their initial value (1), so short
7
+ // content shows no fade. Fade thickness is tunable via `--tw-scroll-fade-size`.
8
+ export const scrollFadePlugin = plugin(function ({ addUtilities, addBase }) {
9
+ addBase({
10
+ '@property --tw-scroll-fade-start': {
11
+ syntax: "'<number>'",
12
+ inherits: 'false',
13
+ 'initial-value': '1',
14
+ },
15
+ '@property --tw-scroll-fade-end': {
16
+ syntax: "'<number>'",
17
+ inherits: 'false',
18
+ 'initial-value': '1',
19
+ },
20
+ '@keyframes tw-scroll-fade-reveal-start': {
21
+ from: { '--tw-scroll-fade-start': '1' },
22
+ to: { '--tw-scroll-fade-start': '0' },
23
+ },
24
+ '@keyframes tw-scroll-fade-reveal-end': {
25
+ from: { '--tw-scroll-fade-end': '0' },
26
+ to: { '--tw-scroll-fade-end': '1' },
27
+ },
28
+ });
29
+
30
+ const scrollFadeMask = (direction: 'bottom' | 'right') =>
31
+ `linear-gradient(to ${direction}, rgb(0 0 0 / var(--tw-scroll-fade-start)) 0, #000 var(--tw-scroll-fade-size), #000 calc(100% - var(--tw-scroll-fade-size)), rgb(0 0 0 / var(--tw-scroll-fade-end)) 100%)`;
32
+
33
+ const scrollFade = (direction: 'bottom' | 'right', axis: 'x' | 'y') => ({
34
+ '--tw-scroll-fade-size': '1.5rem',
35
+ WebkitMaskImage: scrollFadeMask(direction),
36
+ maskImage: scrollFadeMask(direction),
37
+ animation: 'tw-scroll-fade-reveal-start linear both, tw-scroll-fade-reveal-end linear both',
38
+ animationTimeline: `scroll(self ${axis}), scroll(self ${axis})`,
39
+ animationRange: '0 var(--tw-scroll-fade-size), calc(100% - var(--tw-scroll-fade-size)) 100%',
40
+ // Browsers without scroll-driven animations show a static fade on both edges.
41
+ '@supports not (animation-timeline: scroll())': {
42
+ '--tw-scroll-fade-start': '0',
43
+ '--tw-scroll-fade-end': '0',
44
+ },
45
+ });
46
+
47
+ const scrollFadeVertical = scrollFade('bottom', 'y');
48
+ addUtilities({
49
+ '.scroll-fade': scrollFadeVertical,
50
+ '.scroll-fade-y': scrollFadeVertical,
51
+ '.scroll-fade-x': scrollFade('right', 'x'),
52
+ });
53
+ });