@sewadah/selaras 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.
Files changed (46) hide show
  1. package/README.md +36 -7
  2. package/dist/module.json +1 -1
  3. package/dist/module.mjs +18 -15
  4. package/dist/runtime/components/Badge.d.vue.ts +1 -1
  5. package/dist/runtime/components/Badge.vue.d.ts +1 -1
  6. package/dist/runtime/components/ContentToc.vue +14 -7
  7. package/dist/runtime/components/FileUpload.vue +1 -1
  8. package/dist/runtime/components/NavigationMenu.vue +2 -0
  9. package/dist/runtime/components/PinInput.vue +1 -1
  10. package/dist/runtime/components/ProsePre.d.vue.ts +4 -2
  11. package/dist/runtime/components/ProsePre.vue +9 -3
  12. package/dist/runtime/components/ProsePre.vue.d.ts +4 -2
  13. package/dist/runtime/default-colors.css +1 -1
  14. package/dist/runtime/internal/ComboboxSelectBase.vue +1 -1
  15. package/dist/runtime/structural.css +1 -1
  16. package/dist/runtime/theme/avatar.js +7 -7
  17. package/dist/runtime/theme/badge.js +2 -2
  18. package/dist/runtime/theme/checkbox.js +1 -1
  19. package/dist/runtime/theme/date-picker.js +1 -1
  20. package/dist/runtime/theme/file-upload.js +2 -2
  21. package/dist/runtime/theme/icon.js +1 -1
  22. package/dist/runtime/theme/input-number.js +1 -1
  23. package/dist/runtime/theme/input.js +1 -1
  24. package/dist/runtime/theme/pin-input.js +1 -1
  25. package/dist/runtime/theme/progress.js +2 -2
  26. package/dist/runtime/theme/prose.d.ts +6 -0
  27. package/dist/runtime/theme/prose.js +2 -0
  28. package/dist/runtime/theme/radio-group.js +4 -4
  29. package/dist/runtime/theme/rating.js +1 -1
  30. package/dist/runtime/theme/select.js +2 -2
  31. package/dist/runtime/theme/separator.js +1 -1
  32. package/dist/runtime/theme/slider.js +2 -2
  33. package/dist/runtime/theme/splitter-resize-handle.js +1 -1
  34. package/dist/runtime/theme/switch.js +1 -1
  35. package/dist/runtime/theme/textarea.js +1 -1
  36. package/dist/runtime/utils/color-registry.d.ts +3 -1
  37. package/dist/runtime/utils/color-registry.js +4 -0
  38. package/dist/runtime/utils/file-icons.d.ts +8 -0
  39. package/dist/runtime/utils/file-icons.js +131 -0
  40. package/dist/runtime/utils/functional-tokens.d.ts +1 -1
  41. package/dist/runtime/utils/functional-tokens.js +1 -1
  42. package/dist/runtime/utils/navigation-menu.d.ts +3 -0
  43. package/dist/runtime/utils/seed-colors.d.ts +2 -1
  44. package/dist/runtime/utils/seed-colors.js +24 -16
  45. package/dist/tokens/default-colors.tokens.json +100 -100
  46. package/package.json +20 -9
@@ -47,7 +47,7 @@ export const ratingTheme = tv({
47
47
  // backdrop through it, reading as "not filled" with no shape swap
48
48
  // needed - recolored once its own indicator's data-state flips to
49
49
  // active.
50
- fillIcon: "text-transparent transition-colors group-data-[state=active]/step:text-[var(--_selaras-color-fill)]"
50
+ fillIcon: "text-transparent transition-colors group-data-[state=active]/step:text-[var(--_selaras-color-indicator)]"
51
51
  },
52
52
  variants: {
53
53
  orientation: {
@@ -44,7 +44,7 @@ export const selectTheme = tv({
44
44
  viewport: "max-h-72 overflow-y-auto p-1",
45
45
  group: "px-2 pt-2 pb-1 text-xs font-medium text-[var(--selaras-resolved-text-muted)]",
46
46
  item: "relative flex items-center gap-2 rounded-[var(--selaras-resolved-radius-sm)] py-1.5 ps-2 pe-8 text-sm text-[var(--selaras-resolved-text-default)] outline-none cursor-pointer select-none data-[highlighted]:bg-[var(--selaras-resolved-surface-elevated)] data-[disabled]:opacity-50 data-[disabled]:pointer-events-none",
47
- itemIndicator: "absolute end-2 flex items-center text-[var(--_selaras-color-fill)]",
47
+ itemIndicator: "absolute end-2 flex items-center text-[var(--_selaras-color-indicator)]",
48
48
  empty: "px-2 py-6 text-center text-sm text-[var(--selaras-resolved-text-muted)]",
49
49
  arrow: "fill-[var(--selaras-resolved-surface-default)] stroke-[var(--selaras-resolved-border-default)] stroke-1"
50
50
  },
@@ -72,7 +72,7 @@ export const selectTheme = tv({
72
72
  // overrides win over color's - see input.ts for why declaration order
73
73
  // (not runtime call order) is what decides this.
74
74
  invalid: {
75
- true: { trigger: "ring-[var(--_selaras-color-fill)] hover:ring-[var(--_selaras-color-fill)] focus:ring-[var(--_selaras-color-fill)] focus-within:ring-[var(--_selaras-color-fill)] data-[state=open]:ring-[var(--_selaras-color-fill)]" }
75
+ true: { trigger: "ring-[var(--_selaras-color-border)] hover:ring-[var(--_selaras-color-border)] focus:ring-[var(--_selaras-color-focus)] focus-within:ring-[var(--_selaras-color-focus)] data-[state=open]:ring-[var(--_selaras-color-focus)]" }
76
76
  }
77
77
  },
78
78
  defaultVariants: {
@@ -10,7 +10,7 @@ export const separatorTheme = tv({
10
10
  // plain bar; with a label, a second one of these renders after it
11
11
  // (see Separator.vue), splitting the available space evenly on both
12
12
  // sides of the text.
13
- line: "shrink-0 border-[var(--_selaras-color-fill)]",
13
+ line: "shrink-0 border-[var(--_selaras-color-indicator)]",
14
14
  // Always muted, independent of `color` - a colored line with
15
15
  // matching bright label text reads as garish rather than
16
16
  // informative; the label stays legible/neutral regardless of how
@@ -10,8 +10,8 @@ export const sliderTheme = tv({
10
10
  // positioned element with no top/bottom of its own collapses to 0
11
11
  // height. inset-y-0/inset-x-0 below (in the orientation variant)
12
12
  // supply that missing cross-axis size.
13
- range: "absolute rounded-full bg-[var(--_selaras-color-fill)]",
14
- thumb: "block shrink-0 rounded-full bg-[var(--selaras-resolved-surface-default)] shadow-[var(--selaras-resolved-shadow-sm)] ring-2 ring-[var(--_selaras-color-fill)] transition-shadow focus-visible:outline-none focus-visible:ring-4",
13
+ range: "absolute rounded-full bg-[var(--_selaras-color-indicator)]",
14
+ thumb: "block shrink-0 rounded-full bg-[var(--selaras-resolved-surface-default)] shadow-[var(--selaras-resolved-shadow-sm)] ring-2 ring-[var(--_selaras-color-indicator)] transition-shadow focus-visible:outline-none focus-visible:ring-4",
15
15
  // Own addition - Reka's Slider has no tick/mark concept of its own.
16
16
  // Positioned via an inline style (percent along the track), not a
17
17
  // variant - see Slider.vue's own `ticks` computed.
@@ -4,7 +4,7 @@ export const splitterResizeHandleTheme = tv({
4
4
  // A slim hit area with a thinner visible line inside it - the visible
5
5
  // line alone would be too narrow a target to reliably grab.
6
6
  root: "group relative shrink-0 bg-transparent outline-none",
7
- line: "absolute bg-[var(--selaras-resolved-border-default)] transition-colors group-hover:bg-[var(--_selaras-color-fill)] group-data-[state=drag]:bg-[var(--_selaras-color-fill)]"
7
+ line: "absolute bg-[var(--selaras-resolved-border-default)] transition-colors group-hover:bg-[var(--_selaras-color-indicator)] group-data-[state=drag]:bg-[var(--_selaras-color-indicator)]"
8
8
  },
9
9
  variants: {
10
10
  color: {
@@ -74,7 +74,7 @@ export const switchTheme = tv({
74
74
  // its own to recolor (unlike Radio/Checkbox's ring-inset), but an
75
75
  // offset outline left a visible gap between it and the pill, unlike
76
76
  // every other invalid state in this library, which sits flush.
77
- true: { track: "ring-2 ring-[var(--_selaras-color-fill)]", thumb: "data-[state=checked]:before:bg-[var(--_selaras-color-fill-hover)]" }
77
+ true: { track: "ring-2 ring-[var(--_selaras-color-border)]", thumb: "data-[state=checked]:before:bg-[var(--_selaras-color-fill-hover)]" }
78
78
  }
79
79
  },
80
80
  defaultVariants: {
@@ -46,7 +46,7 @@ export const textareaTheme = tv({
46
46
  // override win over color's - see input.ts for why declaration order
47
47
  // (not runtime call order) is what decides this.
48
48
  invalid: {
49
- true: { base: "ring-[var(--_selaras-color-fill)] hover:ring-[var(--_selaras-color-fill)] focus:ring-[var(--_selaras-color-fill)]" }
49
+ true: { base: "ring-[var(--_selaras-color-border)] hover:ring-[var(--_selaras-color-border)] focus:ring-[var(--_selaras-color-focus)]" }
50
50
  }
51
51
  },
52
52
  defaultVariants: {
@@ -18,6 +18,8 @@ export interface ColorRecipe {
18
18
  fillHover: string;
19
19
  fillPressed: string;
20
20
  onFill: string;
21
+ /** Essential unpaired graphics such as progress and selection indicators. */
22
+ indicator: string;
21
23
  subtle: string;
22
24
  subtleHover: string;
23
25
  subtlePressed: string;
@@ -28,7 +30,7 @@ export interface ColorRecipe {
28
30
  border: string;
29
31
  focus: string;
30
32
  }
31
- export type ColorRecipeInput = Pick<ColorRecipe, 'fill' | 'onFill' | 'subtle' | 'onSubtle' | 'text' | 'border'> & Partial<Pick<ColorRecipe, 'fillHover' | 'fillPressed' | 'subtleHover' | 'subtlePressed' | 'textHover' | 'textPressed' | 'focus'>>;
33
+ export type ColorRecipeInput = Pick<ColorRecipe, 'fill' | 'onFill' | 'subtle' | 'onSubtle' | 'text' | 'border'> & Partial<Pick<ColorRecipe, 'fillHover' | 'fillPressed' | 'indicator' | 'subtleHover' | 'subtlePressed' | 'textHover' | 'textPressed' | 'focus'>>;
32
34
  export type RuntimeColorOverrides = Partial<Record<ColorRole, Partial<ColorRecipeInput>>>;
33
35
  export interface RuntimeThemeMode extends ThemeTokenOverrides {
34
36
  colors?: RuntimeColorOverrides;
@@ -38,6 +38,9 @@ export function normalizeColorRecipe(input) {
38
38
  fillHover: input.fillHover ?? "var(--_selaras-color-fill)",
39
39
  fillPressed: input.fillPressed ?? "var(--_selaras-color-fill-hover)",
40
40
  onFill: input.onFill,
41
+ // A recipe's border is already authored for visibility against its
42
+ // surrounding surface, making it the safe shorthand for unpaired marks.
43
+ indicator: input.indicator ?? "var(--_selaras-color-border)",
41
44
  subtle: input.subtle,
42
45
  subtleHover: input.subtleHover ?? "var(--_selaras-color-subtle)",
43
46
  subtlePressed: input.subtlePressed ?? "var(--_selaras-color-subtle-hover)",
@@ -62,6 +65,7 @@ const generatedRoleFields = [
62
65
  "fill-hover",
63
66
  "fill-pressed",
64
67
  "on-fill",
68
+ "indicator",
65
69
  "subtle",
66
70
  "subtle-hover",
67
71
  "subtle-pressed",
@@ -0,0 +1,8 @@
1
+ export declare const defaultFileIcons: Record<string, string>;
2
+ /**
3
+ * Resolves a file-type icon for a code block, preferring a filename's own
4
+ * extension (the more specific signal) over the fence's `language`. Returns
5
+ * undefined when neither maps to a known type, so callers can render no icon
6
+ * rather than a misleading fallback.
7
+ */
8
+ export declare function resolveFileIcon(language?: string, filename?: string): string | undefined;
@@ -0,0 +1,131 @@
1
+ export const defaultFileIcons = {
2
+ "vue": "vscode-icons:file-type-vue",
3
+ "ts": "vscode-icons:file-type-typescript",
4
+ "typescript": "vscode-icons:file-type-typescript",
5
+ "mts": "vscode-icons:file-type-typescript",
6
+ "cts": "vscode-icons:file-type-typescript",
7
+ "tsx": "vscode-icons:file-type-reactts",
8
+ "js": "vscode-icons:file-type-js",
9
+ "javascript": "vscode-icons:file-type-js",
10
+ "mjs": "vscode-icons:file-type-js",
11
+ "cjs": "vscode-icons:file-type-js",
12
+ "jsx": "vscode-icons:file-type-reactjs",
13
+ "html": "vscode-icons:file-type-html",
14
+ "htm": "vscode-icons:file-type-html",
15
+ "css": "vscode-icons:file-type-css",
16
+ "scss": "vscode-icons:file-type-scss",
17
+ "sass": "vscode-icons:file-type-sass",
18
+ "less": "vscode-icons:file-type-less",
19
+ "json": "vscode-icons:file-type-json",
20
+ "jsonc": "vscode-icons:file-type-json",
21
+ "json5": "vscode-icons:file-type-json",
22
+ "md": "vscode-icons:file-type-markdown",
23
+ "markdown": "vscode-icons:file-type-markdown",
24
+ "mdx": "vscode-icons:file-type-markdown",
25
+ "bash": "vscode-icons:file-type-shell",
26
+ "sh": "vscode-icons:file-type-shell",
27
+ "shell": "vscode-icons:file-type-shell",
28
+ "zsh": "vscode-icons:file-type-shell",
29
+ "console": "vscode-icons:file-type-shell",
30
+ "terminal": "vscode-icons:file-type-shell",
31
+ "python": "vscode-icons:file-type-python",
32
+ "py": "vscode-icons:file-type-python",
33
+ "yaml": "vscode-icons:file-type-yaml",
34
+ "yml": "vscode-icons:file-type-yaml",
35
+ "toml": "vscode-icons:file-type-toml",
36
+ "ini": "vscode-icons:file-type-ini",
37
+ "cfg": "vscode-icons:file-type-config",
38
+ "conf": "vscode-icons:file-type-config",
39
+ "config": "vscode-icons:file-type-config",
40
+ "env": "vscode-icons:file-type-dotenv",
41
+ "dotenv": "vscode-icons:file-type-dotenv",
42
+ "go": "vscode-icons:file-type-go",
43
+ "rust": "vscode-icons:file-type-rust",
44
+ "rs": "vscode-icons:file-type-rust",
45
+ "php": "vscode-icons:file-type-php",
46
+ "ruby": "vscode-icons:file-type-ruby",
47
+ "rb": "vscode-icons:file-type-ruby",
48
+ "sql": "vscode-icons:file-type-sql",
49
+ "docker": "vscode-icons:file-type-docker",
50
+ "dockerfile": "vscode-icons:file-type-docker",
51
+ "svelte": "vscode-icons:file-type-svelte",
52
+ "astro": "vscode-icons:file-type-astro",
53
+ "xml": "vscode-icons:file-type-xml",
54
+ "svg": "vscode-icons:file-type-svg",
55
+ "java": "vscode-icons:file-type-java",
56
+ "kotlin": "vscode-icons:file-type-kotlin",
57
+ "kt": "vscode-icons:file-type-kotlin",
58
+ "swift": "vscode-icons:file-type-swift",
59
+ "csharp": "vscode-icons:file-type-csharp",
60
+ "cs": "vscode-icons:file-type-csharp",
61
+ "cpp": "vscode-icons:file-type-cpp",
62
+ "c++": "vscode-icons:file-type-cpp",
63
+ "c": "vscode-icons:file-type-c",
64
+ "vim": "vscode-icons:file-type-vim",
65
+ "lua": "vscode-icons:file-type-lua",
66
+ "nginx": "vscode-icons:file-type-nginx",
67
+ "graphql": "vscode-icons:file-type-graphql",
68
+ "gql": "vscode-icons:file-type-graphql",
69
+ "prisma": "vscode-icons:file-type-prisma",
70
+ "powershell": "vscode-icons:file-type-powershell",
71
+ "ps1": "vscode-icons:file-type-powershell",
72
+ "r": "vscode-icons:file-type-r",
73
+ "elixir": "vscode-icons:file-type-elixir",
74
+ "ex": "vscode-icons:file-type-elixir",
75
+ "exs": "vscode-icons:file-type-elixir",
76
+ "erlang": "vscode-icons:file-type-erlang",
77
+ "erl": "vscode-icons:file-type-erlang",
78
+ "haskell": "vscode-icons:file-type-haskell",
79
+ "hs": "vscode-icons:file-type-haskell",
80
+ "scala": "vscode-icons:file-type-scala",
81
+ "julia": "vscode-icons:file-type-julia",
82
+ "jl": "vscode-icons:file-type-julia",
83
+ "zig": "vscode-icons:file-type-zig",
84
+ "nim": "vscode-icons:file-type-nim",
85
+ "crystal": "vscode-icons:file-type-crystal",
86
+ "solidity": "vscode-icons:file-type-solidity",
87
+ "sol": "vscode-icons:file-type-solidity",
88
+ "terraform": "vscode-icons:file-type-terraform",
89
+ "tf": "vscode-icons:file-type-terraform",
90
+ "cmake": "vscode-icons:file-type-cmake",
91
+ "wasm": "vscode-icons:file-type-wasm",
92
+ "text": "vscode-icons:file-type-text",
93
+ "txt": "vscode-icons:file-type-text",
94
+ "plaintext": "vscode-icons:file-type-text",
95
+ "plain": "vscode-icons:file-type-text",
96
+ "output": "vscode-icons:file-type-text",
97
+ "ansi": "vscode-icons:file-type-text",
98
+ "diff": "vscode-icons:file-type-diff",
99
+ "patch": "vscode-icons:file-type-diff",
100
+ "log": "vscode-icons:file-type-log",
101
+ "image": "vscode-icons:file-type-image",
102
+ "audio": "vscode-icons:file-type-audio",
103
+ "video": "vscode-icons:file-type-video",
104
+ "font": "vscode-icons:file-type-font",
105
+ "zip": "vscode-icons:file-type-zip",
106
+ "git": "vscode-icons:file-type-git",
107
+ "gitignore": "vscode-icons:file-type-git",
108
+ "npm": "vscode-icons:file-type-npm",
109
+ "nuxt": "vscode-icons:file-type-nuxt",
110
+ "ansible": "vscode-icons:file-type-ansible",
111
+ "bicep": "vscode-icons:file-type-bicep"
112
+ };
113
+ function normalizeFileIconKey(value) {
114
+ const key = value?.trim().toLowerCase().replace(/^\./, "");
115
+ return key || void 0;
116
+ }
117
+ function extensionOf(filename) {
118
+ if (!filename)
119
+ return void 0;
120
+ const base = filename.split(/[\\/]/).pop() ?? filename;
121
+ const dot = base.lastIndexOf(".");
122
+ return dot > 0 ? base.slice(dot + 1) : base.replace(/^\./, "");
123
+ }
124
+ export function resolveFileIcon(language, filename) {
125
+ for (const candidate of [extensionOf(filename), language]) {
126
+ const key = normalizeFileIconKey(candidate);
127
+ if (key && defaultFileIcons[key])
128
+ return defaultFileIcons[key];
129
+ }
130
+ return void 0;
131
+ }
@@ -1,6 +1,6 @@
1
1
  /** Functional colors are independent of a component's selected intent role. */
2
2
  export declare const functionalTokenGroups: {
3
- readonly surface: readonly ["default", "elevated", "inverted"];
3
+ readonly surface: readonly ["canvas", "default", "elevated", "inverted"];
4
4
  readonly text: readonly ["default", "muted", "inverted"];
5
5
  readonly border: readonly ["default", "muted", "hover"];
6
6
  };
@@ -1,5 +1,5 @@
1
1
  export const functionalTokenGroups = {
2
- surface: ["default", "elevated", "inverted"],
2
+ surface: ["canvas", "default", "elevated", "inverted"],
3
3
  text: ["default", "muted", "inverted"],
4
4
  border: ["default", "muted", "hover"]
5
5
  };
@@ -2,6 +2,9 @@ export interface NavigationMenuItem {
2
2
  label: string;
3
3
  icon?: string;
4
4
  to?: string;
5
+ target?: string;
6
+ rel?: string;
7
+ ariaLabel?: string;
5
8
  disabled?: boolean;
6
9
  /** Force active state - otherwise auto-detected against the current route when `to` is set. */
7
10
  active?: boolean;
@@ -8,7 +8,8 @@ export interface SeedColorOptions {
8
8
  surfaces?: SeedColorSurfaces;
9
9
  }
10
10
  /**
11
- * Derives a complete, opaque two-mode web ColorRecipe from one opaque sRGB seed.
11
+ * Preserves one opaque sRGB seed as the resting fill and derives a complete,
12
+ * opaque two-mode web ColorRecipe around it.
12
13
  * Custom or unresolved surfaces require explicit recipes instead.
13
14
  */
14
15
  export declare function defineColorFromSeed(seed: string, options?: SeedColorOptions): ColorModePair<ColorRecipe>;
@@ -150,30 +150,38 @@ function requireSeries(mode, family, create) {
150
150
  invalid(`cannot derive the ${mode} ${family} family while preserving its contrast targets; provide an explicit defineColor() recipe.`);
151
151
  }
152
152
  }
153
+ function deriveFillStates(seed, foreground, mode) {
154
+ const preferredTarget = mode === "light" ? black : white;
155
+ const alternateTarget = preferredTarget === black ? white : black;
156
+ for (const target of [preferredTarget, alternateTarget]) {
157
+ for (const scale of [1, 0.75, 0.5, 0.25, 0.125, 0.0625, 0.03125]) {
158
+ const hover = quantize(mixLab(seed, target, 0.06 * scale));
159
+ const pressed = quantize(mixLab(seed, target, 0.12 * scale));
160
+ const colors = [seed, hover, pressed];
161
+ if (new Set(colors.map(toHex)).size === colors.length && colors.every((color) => contrast(color, foreground) >= textMinimum))
162
+ return [hover, pressed];
163
+ }
164
+ }
165
+ invalid(`cannot derive distinct ${mode} fill states while preserving readable content; provide an explicit defineColor() recipe.`);
166
+ }
153
167
  function deriveMode(seed, surface, mode) {
154
168
  const direction = contrast(white, surface) > contrast(black, surface) ? 1 : -1;
155
- const fillCandidates = [black, white].flatMap((foreground) => {
156
- try {
157
- const series = findStateSeries(seed, direction, 0.045, 3, (color) => contrast(color, surface) >= nonTextGuard && contrast(color, foreground) >= textGuard);
158
- return [{ ...series, foreground }];
159
- } catch {
160
- return [];
161
- }
162
- }).sort((left, right) => left.cost + Number(left.collapsed) * 0.02 - (right.cost + Number(right.collapsed) * 0.02));
163
- const fill = fillCandidates[0];
164
- if (!fill)
165
- invalid(`cannot derive the ${mode} fill family while preserving its contrast targets; provide an explicit defineColor() recipe.`);
166
- const fillColor = fill.colors[0];
169
+ const foreground = contrast(seed, black) >= contrast(seed, white) ? black : white;
170
+ if (contrast(seed, foreground) < textMinimum)
171
+ invalid(`cannot preserve the ${mode} fill while deriving readable content; provide an explicit defineColor() recipe.`);
172
+ const [fillHover, fillPressed] = deriveFillStates(seed, foreground, mode);
173
+ const fillColor = seed;
167
174
  const subtle = quantize(mixLab(surface, fillColor, 0.1));
168
175
  const subtleHover = quantize(mixLab(surface, fillColor, 0.14));
169
176
  const subtlePressed = quantize(mixLab(surface, fillColor, 0.18));
170
177
  const text = requireSeries(mode, "text/subtle", () => findStateSeries(seed, direction, 0.03, 3, (color) => [surface, subtle, subtleHover, subtlePressed].every((background) => contrast(color, background) >= textGuard))).colors;
171
178
  const border = requireSeries(mode, "border", () => findStateSeries(seed, direction, 0.02, 1, (color) => contrast(color, surface) >= nonTextGuard)).colors[0];
172
179
  return {
173
- fill: toHex(fill.colors[0]),
174
- fillHover: toHex(fill.colors[1]),
175
- fillPressed: toHex(fill.colors[2]),
176
- onFill: toHex(fill.foreground),
180
+ fill: toHex(fillColor),
181
+ fillHover: toHex(fillHover),
182
+ fillPressed: toHex(fillPressed),
183
+ onFill: toHex(foreground),
184
+ indicator: toHex(border),
177
185
  subtle: toHex(subtle),
178
186
  subtleHover: toHex(subtleHover),
179
187
  subtlePressed: toHex(subtlePressed),