@varialkit/segmentcontrol 0.1.1 → 0.1.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.
package/docs.md CHANGED
@@ -26,6 +26,22 @@ export function ViewSwitcher() {
26
26
  - Use `fullWidth` when the control should span its container.
27
27
  - Prefer 2-5 segments to keep labels readable.
28
28
  - By default, segments size to their content for stable label alignment; `fullWidth` stretches them evenly.
29
+ - Active segments keep the same typography as inactive ones; selection emphasis comes from color, background, and a subtle border instead of a font-weight or shadow change.
30
+ - Use the `radius` prop with `sm`, `md`, `lg`, or `full` to control segment cell rounding; the outer container stays slightly rounder than the cells where the token scale allows it.
31
+
32
+ ## Control Props
33
+
34
+ `SegmentControl` accepts the following core props:
35
+
36
+ | Prop | Type | Description |
37
+ | --- | --- | --- |
38
+ | `value` | `string` | Currently selected segment value. |
39
+ | `onChange` | `(value: string) => void` | Called when selection changes. |
40
+ | `size` | `"small" | "medium" | "large" | "sm" | "md" | "lg"` | Controls control height, spacing, and typography scale. |
41
+ | `radius` | `"sm" | "md" | "lg" | "full"` | Controls segment cell radius using shared radius tokens. |
42
+ | `fullWidth` | `boolean` | Stretches segments evenly across the container. |
43
+ | `movingBackground` | `boolean` | Uses a single animated background indicator that follows hover/focus. |
44
+ | `surfaceStyle` | `"solid" | "translucent" | "glass" | { ... }` | Applies surface material treatment without changing layout tokens. |
29
45
 
30
46
  ## Segment Props
31
47
 
package/examples.tsx CHANGED
@@ -1,11 +1,12 @@
1
1
  import React from "react";
2
- import { iconNames } from "@solara/icons";
3
- import type { SolaraIconName } from "@solara/icons";
2
+ import { iconNames } from "@varialkit/icons";
3
+ import type { SolaraIconName } from "@varialkit/icons";
4
4
  import { SegmentControl } from "./src/SegmentControl";
5
- import type { SegmentControlSize } from "./src/SegmentControl.types";
5
+ import type { SegmentControlRadius, SegmentControlSize } from "./src/SegmentControl.types";
6
6
 
7
7
  type PlaygroundProps = {
8
8
  size: SegmentControlSize;
9
+ radius: SegmentControlRadius;
9
10
  fullWidth: boolean;
10
11
  withIcons: boolean;
11
12
  movingBackground: boolean;
@@ -15,6 +16,7 @@ type PlaygroundProps = {
15
16
 
16
17
  const SegmentControlPlayground = ({
17
18
  size,
19
+ radius,
18
20
  fullWidth,
19
21
  withIcons,
20
22
  movingBackground,
@@ -42,6 +44,7 @@ const SegmentControlPlayground = ({
42
44
  value={value}
43
45
  onChange={setValue}
44
46
  size={size}
47
+ radius={radius}
45
48
  fullWidth={fullWidth}
46
49
  movingBackground={movingBackground}
47
50
  >
@@ -62,7 +65,7 @@ const SegmentControlPlayground = ({
62
65
  export const stories = {
63
66
  playground: {
64
67
  title: "Playground",
65
- description: "Explore size, width, and disabled segment states.",
68
+ description: "Explore size, radius, width, and disabled segment states.",
66
69
  render: (props: PlaygroundProps) => <SegmentControlPlayground {...props} />,
67
70
  controls: [
68
71
  {
@@ -70,6 +73,11 @@ export const stories = {
70
73
  type: "select",
71
74
  options: ["small", "medium", "large"],
72
75
  },
76
+ {
77
+ name: "radius",
78
+ type: "select",
79
+ options: ["sm", "md", "lg", "full"],
80
+ },
73
81
  {
74
82
  name: "fullWidth",
75
83
  type: "boolean",
@@ -100,6 +108,7 @@ export const stories = {
100
108
  ],
101
109
  initialProps: {
102
110
  size: "medium",
111
+ radius: "full",
103
112
  fullWidth: false,
104
113
  withIcons: false,
105
114
  movingBackground: false,
@@ -130,7 +139,7 @@ export const stories = {
130
139
  </SegmentControl>
131
140
  </div>
132
141
  ),
133
- code: `import { SegmentControl } from "@solara/segmentcontrol";
142
+ code: `import { SegmentControl } from "@varialkit/segmentcontrol";
134
143
 
135
144
  export function Example() {
136
145
  return (
@@ -166,7 +175,7 @@ export function Example() {
166
175
  <SegmentControl.Segment value="settings" ariaLabel="Settings" icon="arrow_swap_16" />
167
176
  </SegmentControl>
168
177
  ),
169
- code: `import { SegmentControl } from "@solara/segmentcontrol";
178
+ code: `import { SegmentControl } from "@varialkit/segmentcontrol";
170
179
 
171
180
  export function Example() {
172
181
  return (
@@ -196,7 +205,7 @@ export function Example() {
196
205
  </SegmentControl.Segment>
197
206
  </SegmentControl>
198
207
  ),
199
- code: `import { SegmentControl } from "@solara/segmentcontrol";
208
+ code: `import { SegmentControl } from "@varialkit/segmentcontrol";
200
209
 
201
210
  export function Example() {
202
211
  return (
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@varialkit/segmentcontrol",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "type": "module",
5
5
  "main": "src/index.ts",
6
6
  "types": "src/index.ts",
@@ -9,7 +9,7 @@
9
9
  "./examples": "./examples.tsx"
10
10
  },
11
11
  "dependencies": {
12
- "@varialkit/icons": "0.1.1"
12
+ "@varialkit/icons": "0.1.3"
13
13
  },
14
14
  "files": [
15
15
  "src",
@@ -4,6 +4,7 @@
4
4
  --segment-control-surface-color-rgb: var(--color-surface-100-rgb);
5
5
  --surface-border-color: var(--color-divider-secondary);
6
6
  --surface-border-color-rgb: var(--color-divider-secondary-rgb);
7
+ --segment-control-selected-ring-rgb: var(--color-divider-primary-rgb);
7
8
  --surface-opacity: 1;
8
9
  --surface-blur: 0px;
9
10
  --surface-shadow: var(--elevation-1);
@@ -14,6 +15,7 @@
14
15
  --segment-control-bg-active: var(--color-surface-0);
15
16
  --segment-control-bg-hover: var(--color-surface-200);
16
17
  --segment-control-bg-indicator: var(--segment-control-bg-active);
18
+ --segment-control-selected-ring: rgba(var(--segment-control-selected-ring-rgb), 0.5);
17
19
  --segment-control-shadow: var(--elevation-1);
18
20
  --segment-padding-y: var(--space-2);
19
21
  --segment-padding-x: var(--space-4);
@@ -22,12 +24,14 @@
22
24
  --segment-icon-size: 16px;
23
25
  --segment-gap: var(--space-2);
24
26
  --segment-height: var(--space-9);
27
+ --segment-cell-radius: var(--radius-pill);
28
+ --segment-container-radius: var(--radius-pill);
25
29
 
26
30
  position: relative;
27
31
  display: inline-flex;
28
32
  align-items: center;
29
33
  gap: calc(var(--space-1) * var(--spacing-multiplier));
30
- border-radius: var(--radius-pill);
34
+ border-radius: calc(var(--segment-container-radius) * var(--radius-multiplier));
31
35
  background-color: rgba(var(--segment-control-surface-color-rgb), var(--surface-opacity));
32
36
  padding: calc(var(--space-1) * var(--spacing-multiplier));
33
37
  box-shadow: transparent;
@@ -50,18 +54,37 @@
50
54
  var(--segment-indicator-top, 0px)
51
55
  );
52
56
  background-color: var(--segment-control-bg-indicator);
53
- border-radius: var(--radius-pill);
54
- box-shadow: var(--segment-control-shadow);
57
+ border-radius: calc(var(--segment-cell-radius) * var(--radius-multiplier));
58
+ border: 1px solid var(--segment-control-selected-ring);
55
59
  opacity: var(--segment-indicator-opacity, 0);
56
60
  transition: transform 0.2s ease, width 0.2s ease, height 0.2s ease, opacity 0.2s ease;
57
61
  pointer-events: none;
58
62
  z-index: 0;
59
63
  }
60
64
 
65
+ .solara-segment-control--radius-sm {
66
+ --segment-cell-radius: var(--radius-sm);
67
+ --segment-container-radius: var(--radius-md);
68
+ }
69
+
70
+ .solara-segment-control--radius-md {
71
+ --segment-cell-radius: var(--radius-md);
72
+ --segment-container-radius: var(--radius-3);
73
+ }
74
+
75
+ .solara-segment-control--radius-lg {
76
+ --segment-cell-radius: var(--radius-3);
77
+ --segment-container-radius: var(--radius-lg);
78
+ }
79
+
80
+ .solara-segment-control--radius-full {
81
+ --segment-cell-radius: var(--radius-full);
82
+ --segment-container-radius: var(--radius-full);
83
+ }
84
+
61
85
  .solara-segment-control--moving-bg {
62
86
  .solara-segment-control__segment {
63
87
  background-color: transparent;
64
- box-shadow: none;
65
88
  position: relative;
66
89
  z-index: 1;
67
90
  }
@@ -72,7 +95,7 @@
72
95
 
73
96
  .solara-segment-control__segment[data-state="active"] {
74
97
  background-color: transparent;
75
- box-shadow: none;
98
+ border-color: transparent;
76
99
  }
77
100
  }
78
101
 
@@ -113,8 +136,8 @@
113
136
  line-height: var(--segment-line-height);
114
137
  color: var(--segment-control-text);
115
138
  background-color: transparent;
116
- border: none;
117
- border-radius: var(--radius-pill);
139
+ border: 1px solid transparent;
140
+ border-radius: calc(var(--segment-cell-radius) * var(--radius-multiplier));
118
141
  cursor: pointer;
119
142
  transition: background-color 0.2s ease, color 0.2s ease, box-shadow 0.2s ease;
120
143
  white-space: nowrap;
@@ -145,8 +168,7 @@
145
168
  .solara-segment-control__segment[data-state="active"] {
146
169
  color: var(--segment-control-text-active);
147
170
  background-color: var(--segment-control-bg-active);
148
- box-shadow: var(--elevation-1);
149
- font-weight: 600;
171
+ border-color: var(--segment-control-selected-ring);
150
172
  }
151
173
 
152
174
  .solara-segment-control__segment:disabled,
@@ -1,7 +1,12 @@
1
1
  import React, { Children, useCallback, useEffect, useMemo, useRef, useState } from "react";
2
- import { Icon } from "@solara/icons";
3
- import type { IconProps } from "@solara/icons";
4
- import type { SegmentControlProps, SegmentControlSize, SegmentProps } from "./SegmentControl.types";
2
+ import { Icon } from "@varialkit/icons";
3
+ import type { IconProps } from "@varialkit/icons";
4
+ import type {
5
+ SegmentControlProps,
6
+ SegmentControlRadius,
7
+ SegmentControlSize,
8
+ SegmentProps,
9
+ } from "./SegmentControl.types";
5
10
  import "./SegmentControl.scss";
6
11
 
7
12
  const sizeAliasMap: Record<SegmentControlSize, "small" | "medium" | "large"> = {
@@ -13,6 +18,13 @@ const sizeAliasMap: Record<SegmentControlSize, "small" | "medium" | "large"> = {
13
18
  large: "large",
14
19
  };
15
20
 
21
+ const radiusAliasMap: Record<SegmentControlRadius, "sm" | "md" | "lg" | "full"> = {
22
+ sm: "sm",
23
+ md: "md",
24
+ lg: "lg",
25
+ full: "full",
26
+ };
27
+
16
28
  const classNames = (...classes: Array<string | undefined | false | null>) =>
17
29
  classes.filter(Boolean).join(" ");
18
30
 
@@ -60,6 +72,7 @@ export const SegmentControl: SegmentControlComponent = ({
60
72
  onChange,
61
73
  fullWidth = false,
62
74
  size = "medium",
75
+ radius = "full",
63
76
  movingBackground = false,
64
77
  surfaceStyle,
65
78
  children,
@@ -68,6 +81,7 @@ export const SegmentControl: SegmentControlComponent = ({
68
81
  ...props
69
82
  }: SegmentControlProps) => {
70
83
  const resolvedSize = sizeAliasMap[size];
84
+ const resolvedRadius = radiusAliasMap[radius];
71
85
  // Container ref is used to compute relative offsets for the moving indicator.
72
86
  const containerRef = useRef<HTMLDivElement | null>(null);
73
87
  // Each segment stores its DOM node so we can measure width/position on demand.
@@ -170,7 +184,7 @@ export const SegmentControl: SegmentControlComponent = ({
170
184
 
171
185
  // Surface styling is applied via data attributes so theme defaults remain centralized.
172
186
  const surfaceAttributes: Record<string, string | undefined> = {};
173
- const surfaceStyleVars: React.CSSProperties = {};
187
+ const surfaceStyleVars: React.CSSProperties & Record<string, string> = {};
174
188
 
175
189
  if (surfaceStyle) {
176
190
  if (typeof surfaceStyle === "string") {
@@ -198,6 +212,7 @@ export const SegmentControl: SegmentControlComponent = ({
198
212
  className={classNames(
199
213
  "solara-segment-control",
200
214
  `solara-segment-control--size-${resolvedSize}`,
215
+ `solara-segment-control--radius-${resolvedRadius}`,
201
216
  fullWidth ? "solara-segment-control--full-width" : null,
202
217
  movingBackground ? "solara-segment-control--moving-bg" : null,
203
218
  className
@@ -1,8 +1,10 @@
1
1
  import React from "react";
2
- import type { IconProps } from "@solara/icons";
2
+ import type { IconProps } from "@varialkit/icons";
3
3
 
4
4
  export type SegmentControlSize = "small" | "medium" | "large" | "sm" | "md" | "lg";
5
5
 
6
+ export type SegmentControlRadius = "sm" | "md" | "lg" | "full";
7
+
6
8
  export type SegmentControlSurfaceStyle =
7
9
  | "solid"
8
10
  | "translucent"
@@ -32,6 +34,10 @@ export interface SegmentControlProps
32
34
  * Size of the segment control.
33
35
  */
34
36
  size?: SegmentControlSize;
37
+ /**
38
+ * Controls the rounding of segment cells, with the container rendered slightly rounder when possible.
39
+ */
40
+ radius?: SegmentControlRadius;
35
41
  /**
36
42
  * Controls surface material treatment without changing layout tokens.
37
43
  */