@moises.ai/design-system 4.18.11 → 4.18.13

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": "@moises.ai/design-system",
3
- "version": "4.18.11",
3
+ "version": "4.18.13",
4
4
  "description": "Design System package based on @radix-ui/themes with custom defaults",
5
5
  "private": false,
6
6
  "type": "module",
@@ -53,7 +53,7 @@ const ProjectItem = ({
53
53
 
54
54
  const handleInsertAllTracks = useCallback((e) => {
55
55
  e.stopPropagation()
56
- const tracksFiltered = allTracks.filter((track) => !track.loading && track.transfers.length > 0)
56
+ const tracksFiltered = allTracks.filter((track) => !track.loading && track.transfers?.length > 0)
57
57
  onInsertAllTracks?.(tracksFiltered)
58
58
  }, [onInsertAllTracks, allTracks])
59
59
 
@@ -1,4 +1,3 @@
1
- import React from 'react'
2
1
  import {
3
2
  Flex,
4
3
  SegmentedControl as SegmentedControlRadix,
@@ -15,6 +14,9 @@ export const SegmentedControl = ({
15
14
  iconProps = {},
16
15
  ...props
17
16
  }) => {
17
+ const hasIconWithLabel = items.some((item) => item.icon && item.label)
18
+ const isIconOnly = items.length > 0 && items.every((item) => item.icon && !item.label)
19
+
18
20
  return (
19
21
  <Flex padding="1" width="100%">
20
22
  <SegmentedControlRadix.Root
@@ -24,22 +26,31 @@ export const SegmentedControl = ({
24
26
  variant="surface"
25
27
  radius="medium"
26
28
  className={classNames('customSegmentedControl', className, {
27
- hasIconSegmentedControl: items.some((item) => item.icon),
29
+ hasIconSegmentedControl: hasIconWithLabel,
30
+ isIconOnlySegmentedControl: isIconOnly,
28
31
  })}
29
32
  {...props}
30
33
  >
31
- {items.map((item) => (
32
- <SegmentedControlRadix.Item
33
- key={item.value}
34
- value={item.value}
35
- className={classNames('customSegmentedControlItem', {
36
- hasIcon: item.icon,
37
- })}
38
- >
39
- {item.icon && <item.icon {...iconProps} />}
40
- {item.label}
41
- </SegmentedControlRadix.Item>
42
- ))}
34
+ {items.map((item) => {
35
+ const isItemIconOnly = Boolean(item.icon && !item.label)
36
+
37
+ return (
38
+ <SegmentedControlRadix.Item
39
+ key={item.value}
40
+ value={item.value}
41
+ aria-label={
42
+ isItemIconOnly ? item.ariaLabel || item.value : undefined
43
+ }
44
+ className={classNames('customSegmentedControlItem', {
45
+ hasIcon: item.icon && item.label,
46
+ isIconOnly: isItemIconOnly,
47
+ })}
48
+ >
49
+ {item.icon && <item.icon {...iconProps} />}
50
+ {item.label}
51
+ </SegmentedControlRadix.Item>
52
+ )
53
+ })}
43
54
  </SegmentedControlRadix.Root>
44
55
  </Flex>
45
56
  )
@@ -2,7 +2,13 @@ import { Flex } from '@radix-ui/themes'
2
2
  import { SegmentedControl } from './SegmentedControl'
3
3
  import { useState } from 'react'
4
4
 
5
- import { BassIcon, DrumsIcon, ElectricGuitarIcon, PianoIcon } from '../../icons'
5
+ import {
6
+ AcousticGuitarIcon,
7
+ BassIcon,
8
+ DrumsIcon,
9
+ ElectricGuitarIcon,
10
+ PianoIcon,
11
+ } from '../../icons'
6
12
 
7
13
  export default {
8
14
  title: 'Components/SegmentedControl',
@@ -30,7 +36,7 @@ import { SegmentedControl } from '@moises.ai/design-system'
30
36
  size="2"
31
37
  />
32
38
 
33
- // With icons and custom icon props
39
+ // With icons and labels
34
40
  <SegmentedControl
35
41
  items={[
36
42
  { value: 'bass', label: 'Bass', icon: BassIcon },
@@ -40,6 +46,18 @@ import { SegmentedControl } from '@moises.ai/design-system'
40
46
  handleTypeChange={handleTypeChange}
41
47
  iconProps={{ width: 20, height: 20 }}
42
48
  />
49
+
50
+ // Icon-only (omit label; optionally pass ariaLabel for accessibility)
51
+ <SegmentedControl
52
+ items={[
53
+ { value: 'guitar', icon: ElectricGuitarIcon, ariaLabel: 'Electric guitar' },
54
+ { value: 'piano', icon: PianoIcon, ariaLabel: 'Piano' },
55
+ { value: 'acoustic', icon: AcousticGuitarIcon, ariaLabel: 'Acoustic guitar' },
56
+ ]}
57
+ selectedType={selectedType}
58
+ handleTypeChange={handleTypeChange}
59
+ iconProps={{ width: 18, height: 18 }}
60
+ />
43
61
  \`\`\`
44
62
 
45
63
  ## Component API
@@ -49,8 +67,9 @@ import { SegmentedControl } from '@moises.ai/design-system'
49
67
  items: [
50
68
  {
51
69
  value: string, // The value of the item
52
- label: string, // The label of the item
53
- icon?: React.ComponentType // The icon component (optional)
70
+ label?: string, // The label of the item (omit for icon-only)
71
+ icon?: React.ComponentType, // The icon component (optional)
72
+ ariaLabel?: string // Accessible name when using icon-only (falls back to value)
54
73
  }
55
74
  ],
56
75
  selectedType: string, // The value of the selected item
@@ -60,6 +79,8 @@ import { SegmentedControl } from '@moises.ai/design-system'
60
79
  iconProps?: object, // Props to pass to all icons (e.g., { width: 20, height: 20 })
61
80
  }
62
81
  \`\`\`
82
+
83
+ When every item has an \`icon\` and no \`label\`, the control switches to icon-only layout automatically.
63
84
  `,
64
85
  },
65
86
  },
@@ -131,3 +152,45 @@ export const WithIcons = {
131
152
  )
132
153
  },
133
154
  }
155
+
156
+ export const IconOnly = {
157
+ args: {
158
+ items: [
159
+ {
160
+ value: 'guitar',
161
+ icon: ElectricGuitarIcon,
162
+ ariaLabel: 'Electric guitar',
163
+ },
164
+ { value: 'piano', icon: PianoIcon, ariaLabel: 'Piano' },
165
+ {
166
+ value: 'acoustic',
167
+ icon: AcousticGuitarIcon,
168
+ ariaLabel: 'Acoustic guitar',
169
+ },
170
+ ],
171
+ iconProps: { width: 18, height: 18 },
172
+ initialSelectedType: 'guitar',
173
+ },
174
+ parameters: {
175
+ docs: {
176
+ description: {
177
+ story:
178
+ 'Omit `label` on every item to enable the icon-only layout. Prefer `ariaLabel` for screen readers.',
179
+ },
180
+ },
181
+ },
182
+ render: (args) => {
183
+ const [selectedType, setSelectedType] = useState(args.initialSelectedType)
184
+ return (
185
+ <Flex width="200px">
186
+ <SegmentedControl
187
+ {...args}
188
+ selectedType={selectedType}
189
+ handleTypeChange={(value) => {
190
+ setSelectedType(value)
191
+ }}
192
+ />
193
+ </Flex>
194
+ )
195
+ },
196
+ }
@@ -12,6 +12,10 @@
12
12
  height: auto !important;
13
13
  }
14
14
 
15
+ .isIconOnlySegmentedControl {
16
+ height: auto !important;
17
+ }
18
+
15
19
  .rt-SegmentedControlIndicator {
16
20
  &::before {
17
21
  border-radius: 4px !important;
@@ -53,3 +57,17 @@
53
57
  padding-top: 16px;
54
58
  }
55
59
  }
60
+
61
+ .isIconOnly {
62
+ .rt-SegmentedControlItemLabel {
63
+ flex-direction: row;
64
+ gap: 0;
65
+ min-width: 0;
66
+ padding: 8px 12px;
67
+ }
68
+
69
+ svg {
70
+ display: block;
71
+ flex-shrink: 0;
72
+ }
73
+ }