@tremolo-ui/react 0.0.11 → 0.1.0-alpha.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 (153) hide show
  1. package/dist/cjs/index.js +711 -395
  2. package/dist/cjs/index.js.map +1 -1
  3. package/dist/cjs/types/components/AnimationCanvas/index.d.ts +2 -2
  4. package/dist/cjs/types/components/AnimationCanvas/index.d.ts.map +1 -1
  5. package/dist/cjs/types/components/AnimationKnob/index.d.ts +10 -3
  6. package/dist/cjs/types/components/AnimationKnob/index.d.ts.map +1 -1
  7. package/dist/cjs/types/components/Knob/index.d.ts +25 -3
  8. package/dist/cjs/types/components/Knob/index.d.ts.map +1 -1
  9. package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts +2 -0
  10. package/dist/cjs/types/components/NumberInput/DecrementStepper.d.ts.map +1 -1
  11. package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts +2 -0
  12. package/dist/cjs/types/components/NumberInput/IncrementStepper.d.ts.map +1 -1
  13. package/dist/cjs/types/components/NumberInput/InternalInput.d.ts +18 -0
  14. package/dist/cjs/types/components/NumberInput/InternalInput.d.ts.map +1 -0
  15. package/dist/cjs/types/components/NumberInput/Stepper.d.ts +2 -0
  16. package/dist/cjs/types/components/NumberInput/Stepper.d.ts.map +1 -1
  17. package/dist/cjs/types/components/NumberInput/context.d.ts +3 -2
  18. package/dist/cjs/types/components/NumberInput/context.d.ts.map +1 -1
  19. package/dist/cjs/types/components/NumberInput/index.d.ts +12 -3
  20. package/dist/cjs/types/components/NumberInput/index.d.ts.map +1 -1
  21. package/dist/cjs/types/components/Piano/KeyLabel.d.ts +1 -3
  22. package/dist/cjs/types/components/Piano/KeyLabel.d.ts.map +1 -1
  23. package/dist/cjs/types/components/Piano/context.d.ts +24 -0
  24. package/dist/cjs/types/components/Piano/context.d.ts.map +1 -0
  25. package/dist/cjs/types/components/Piano/index.d.ts +15 -12
  26. package/dist/cjs/types/components/Piano/index.d.ts.map +1 -1
  27. package/dist/cjs/types/components/Piano/key.d.ts +14 -19
  28. package/dist/cjs/types/components/Piano/key.d.ts.map +1 -1
  29. package/dist/cjs/types/components/Piano/keyboardShortcuts.d.ts +2 -2
  30. package/dist/cjs/types/components/Slider/Scale.d.ts +1 -3
  31. package/dist/cjs/types/components/Slider/Scale.d.ts.map +1 -1
  32. package/dist/cjs/types/components/Slider/Thumb.d.ts +1 -0
  33. package/dist/cjs/types/components/Slider/Thumb.d.ts.map +1 -1
  34. package/dist/cjs/types/components/Slider/Track.d.ts +2 -2
  35. package/dist/cjs/types/components/Slider/Track.d.ts.map +1 -1
  36. package/dist/cjs/types/components/Slider/index.d.ts +5 -1
  37. package/dist/cjs/types/components/Slider/index.d.ts.map +1 -1
  38. package/dist/cjs/types/components/WheelObserver/index.d.ts +3 -3
  39. package/dist/cjs/types/components/WheelObserver/index.d.ts.map +1 -1
  40. package/dist/cjs/types/components/XYPad/Area.d.ts +3 -3
  41. package/dist/cjs/types/components/XYPad/Area.d.ts.map +1 -1
  42. package/dist/cjs/types/components/XYPad/Thumb.d.ts +1 -0
  43. package/dist/cjs/types/components/XYPad/Thumb.d.ts.map +1 -1
  44. package/dist/cjs/types/components/XYPad/index.d.ts +6 -1
  45. package/dist/cjs/types/components/XYPad/index.d.ts.map +1 -1
  46. package/dist/cjs/types/hooks/useDrag.d.ts.map +1 -1
  47. package/dist/cjs/types/hooks/useDragWithElement.d.ts +16 -0
  48. package/dist/cjs/types/hooks/useDragWithElement.d.ts.map +1 -0
  49. package/dist/cjs/types/hooks/useInterval.d.ts +2 -0
  50. package/dist/cjs/types/hooks/useInterval.d.ts.map +1 -0
  51. package/dist/cjs/types/hooks/useLongPress.d.ts +2 -0
  52. package/dist/cjs/types/hooks/useLongPress.d.ts.map +1 -0
  53. package/dist/cjs/types/index.d.ts +5 -0
  54. package/dist/cjs/types/index.d.ts.map +1 -1
  55. package/dist/esm/index.js +706 -396
  56. package/dist/esm/index.js.map +1 -1
  57. package/dist/esm/types/components/AnimationCanvas/index.d.ts +2 -2
  58. package/dist/esm/types/components/AnimationCanvas/index.d.ts.map +1 -1
  59. package/dist/esm/types/components/AnimationKnob/index.d.ts +10 -3
  60. package/dist/esm/types/components/AnimationKnob/index.d.ts.map +1 -1
  61. package/dist/esm/types/components/Knob/index.d.ts +25 -3
  62. package/dist/esm/types/components/Knob/index.d.ts.map +1 -1
  63. package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts +2 -0
  64. package/dist/esm/types/components/NumberInput/DecrementStepper.d.ts.map +1 -1
  65. package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts +2 -0
  66. package/dist/esm/types/components/NumberInput/IncrementStepper.d.ts.map +1 -1
  67. package/dist/esm/types/components/NumberInput/InternalInput.d.ts +18 -0
  68. package/dist/esm/types/components/NumberInput/InternalInput.d.ts.map +1 -0
  69. package/dist/esm/types/components/NumberInput/Stepper.d.ts +2 -0
  70. package/dist/esm/types/components/NumberInput/Stepper.d.ts.map +1 -1
  71. package/dist/esm/types/components/NumberInput/context.d.ts +3 -2
  72. package/dist/esm/types/components/NumberInput/context.d.ts.map +1 -1
  73. package/dist/esm/types/components/NumberInput/index.d.ts +12 -3
  74. package/dist/esm/types/components/NumberInput/index.d.ts.map +1 -1
  75. package/dist/esm/types/components/Piano/KeyLabel.d.ts +1 -3
  76. package/dist/esm/types/components/Piano/KeyLabel.d.ts.map +1 -1
  77. package/dist/esm/types/components/Piano/context.d.ts +24 -0
  78. package/dist/esm/types/components/Piano/context.d.ts.map +1 -0
  79. package/dist/esm/types/components/Piano/index.d.ts +15 -12
  80. package/dist/esm/types/components/Piano/index.d.ts.map +1 -1
  81. package/dist/esm/types/components/Piano/key.d.ts +14 -19
  82. package/dist/esm/types/components/Piano/key.d.ts.map +1 -1
  83. package/dist/esm/types/components/Piano/keyboardShortcuts.d.ts +2 -2
  84. package/dist/esm/types/components/Slider/Scale.d.ts +1 -3
  85. package/dist/esm/types/components/Slider/Scale.d.ts.map +1 -1
  86. package/dist/esm/types/components/Slider/Thumb.d.ts +1 -0
  87. package/dist/esm/types/components/Slider/Thumb.d.ts.map +1 -1
  88. package/dist/esm/types/components/Slider/Track.d.ts +2 -2
  89. package/dist/esm/types/components/Slider/Track.d.ts.map +1 -1
  90. package/dist/esm/types/components/Slider/index.d.ts +5 -1
  91. package/dist/esm/types/components/Slider/index.d.ts.map +1 -1
  92. package/dist/esm/types/components/WheelObserver/index.d.ts +3 -3
  93. package/dist/esm/types/components/WheelObserver/index.d.ts.map +1 -1
  94. package/dist/esm/types/components/XYPad/Area.d.ts +3 -3
  95. package/dist/esm/types/components/XYPad/Area.d.ts.map +1 -1
  96. package/dist/esm/types/components/XYPad/Thumb.d.ts +1 -0
  97. package/dist/esm/types/components/XYPad/Thumb.d.ts.map +1 -1
  98. package/dist/esm/types/components/XYPad/index.d.ts +6 -1
  99. package/dist/esm/types/components/XYPad/index.d.ts.map +1 -1
  100. package/dist/esm/types/hooks/useDrag.d.ts.map +1 -1
  101. package/dist/esm/types/hooks/useDragWithElement.d.ts +16 -0
  102. package/dist/esm/types/hooks/useDragWithElement.d.ts.map +1 -0
  103. package/dist/esm/types/hooks/useInterval.d.ts +2 -0
  104. package/dist/esm/types/hooks/useInterval.d.ts.map +1 -0
  105. package/dist/esm/types/hooks/useLongPress.d.ts +2 -0
  106. package/dist/esm/types/hooks/useLongPress.d.ts.map +1 -0
  107. package/dist/esm/types/index.d.ts +5 -0
  108. package/dist/esm/types/index.d.ts.map +1 -1
  109. package/dist/styles/index.css +117 -33
  110. package/package.json +3 -2
  111. package/src/components/AnimationCanvas/index.tsx +14 -6
  112. package/src/components/AnimationKnob/index.tsx +216 -187
  113. package/src/components/Knob/index.tsx +244 -171
  114. package/src/components/NumberInput/DecrementStepper.tsx +9 -2
  115. package/src/components/NumberInput/IncrementStepper.tsx +9 -2
  116. package/src/components/NumberInput/InternalInput.tsx +219 -0
  117. package/src/components/NumberInput/Stepper.tsx +2 -0
  118. package/src/components/NumberInput/context.tsx +20 -8
  119. package/src/components/NumberInput/index.css +76 -22
  120. package/src/components/NumberInput/index.tsx +94 -162
  121. package/src/components/Piano/KeyLabel.tsx +9 -5
  122. package/src/components/Piano/context.tsx +108 -0
  123. package/src/components/Piano/index.css +24 -6
  124. package/src/components/Piano/index.tsx +192 -122
  125. package/src/components/Piano/key.tsx +215 -0
  126. package/src/components/Piano/keyboardShortcuts.ts +2 -2
  127. package/src/components/Slider/Scale.tsx +1 -4
  128. package/src/components/Slider/Thumb.tsx +4 -0
  129. package/src/components/Slider/Track.tsx +5 -2
  130. package/src/components/Slider/index.css +5 -2
  131. package/src/components/Slider/index.tsx +84 -71
  132. package/src/components/WheelObserver/index.tsx +4 -2
  133. package/src/components/XYPad/Area.tsx +7 -6
  134. package/src/components/XYPad/Thumb.tsx +6 -0
  135. package/src/components/XYPad/index.css +12 -2
  136. package/src/components/XYPad/index.tsx +116 -90
  137. package/src/hooks/useDrag.ts +6 -7
  138. package/src/hooks/useDragWithElement.ts +76 -0
  139. package/src/hooks/useInterval.ts +27 -0
  140. package/src/hooks/useLongPress.ts +31 -0
  141. package/src/index.ts +6 -0
  142. package/src/styles/index.css +0 -1
  143. package/dist/cjs/types/components/Piano/BlackKey.d.ts +0 -5
  144. package/dist/cjs/types/components/Piano/BlackKey.d.ts.map +0 -1
  145. package/dist/cjs/types/components/Piano/WhiteKey.d.ts +0 -7
  146. package/dist/cjs/types/components/Piano/WhiteKey.d.ts.map +0 -1
  147. package/dist/esm/types/components/Piano/BlackKey.d.ts +0 -5
  148. package/dist/esm/types/components/Piano/BlackKey.d.ts.map +0 -1
  149. package/dist/esm/types/components/Piano/WhiteKey.d.ts +0 -7
  150. package/dist/esm/types/components/Piano/WhiteKey.d.ts.map +0 -1
  151. package/src/components/Piano/BlackKey.tsx +0 -118
  152. package/src/components/Piano/WhiteKey.tsx +0 -120
  153. package/src/components/Piano/key.ts +0 -46
@@ -0,0 +1,219 @@
1
+ import clsx from 'clsx'
2
+ import {
3
+ ComponentPropsWithoutRef,
4
+ forwardRef,
5
+ useCallback,
6
+ useImperativeHandle,
7
+ useMemo,
8
+ useRef,
9
+ useState,
10
+ } from 'react'
11
+
12
+ import {
13
+ clamp,
14
+ InputEventOption,
15
+ normalizeValue,
16
+ rawValue,
17
+ stepValue,
18
+ } from '@tremolo-ui/functions'
19
+ import { parseValue } from '@tremolo-ui/functions/NumberInput'
20
+
21
+ import { useRefCallbackEvent } from '../../hooks/useRefCallbackEvent'
22
+
23
+ import { safeClamp, useNumberInputContext } from './context'
24
+
25
+ import { NumberInputMethods } from '.'
26
+
27
+ interface InternalProps {
28
+ disabled: boolean
29
+ readonly: boolean
30
+ wheel: InputEventOption | null
31
+ keyboard: InputEventOption | null
32
+
33
+ selectWithFocus?: 'all' | 'number' | 'none'
34
+ blurOnEnter?: boolean
35
+ keepWithinRange?: boolean
36
+ clampValueOnBlur?: boolean
37
+
38
+ onChange?: (value: number, text: string) => void
39
+ onFocus?: (
40
+ value: number,
41
+ text: string,
42
+ event: React.FocusEvent<HTMLInputElement, Element>,
43
+ ) => void
44
+ onBlur?: (
45
+ value: number,
46
+ text: string,
47
+ event: React.FocusEvent<HTMLInputElement, Element>,
48
+ ) => void
49
+ }
50
+
51
+ type InternalPropsWithAttributes = InternalProps &
52
+ Omit<ComponentPropsWithoutRef<'input'>, keyof InternalProps>
53
+
54
+ export const InternalInput = forwardRef<
55
+ NumberInputMethods,
56
+ InternalPropsWithAttributes
57
+ >(
58
+ (
59
+ {
60
+ disabled,
61
+ readonly,
62
+ selectWithFocus,
63
+ blurOnEnter,
64
+ clampValueOnBlur,
65
+ wheel,
66
+ keyboard,
67
+ className,
68
+ onChange,
69
+ onFocus,
70
+ onBlur,
71
+ onKeyDown,
72
+ children: _children,
73
+ ...props
74
+ }: InternalPropsWithAttributes,
75
+ ref,
76
+ ) => {
77
+ const elmRef = useRef<HTMLInputElement>(null)
78
+ const [editing, setEditing] = useState(false)
79
+ const value = useNumberInputContext((s) => s.value)
80
+ const valueAsNumber = useNumberInputContext((s) => s.valueAsNumber)
81
+ const min = useNumberInputContext((s) => s.min)
82
+ const max = useNumberInputContext((s) => s.max)
83
+ const step = useNumberInputContext((s) => s.step)
84
+ const units = useNumberInputContext((s) => s.units)
85
+ const digit = useNumberInputContext((s) => s.digit)
86
+ const change = useNumberInputContext((s) => s.change)
87
+
88
+ const error = useMemo(() => {
89
+ if (editing) return false
90
+ const v = valueAsNumber
91
+ return (min ?? -Infinity) > v || v > (max ?? Infinity)
92
+ }, [editing, max, min, valueAsNumber])
93
+
94
+ const updateValueByEvent = useCallback(
95
+ (eventType: InputEventOption[0], x: number) => {
96
+ let newValue
97
+ if (eventType == 'normalized') {
98
+ if (!min || !max) {
99
+ throw new Error('required parameter: min, max') // TODO
100
+ }
101
+ const n = normalizeValue(valueAsNumber, min, max)
102
+ newValue = rawValue(n + x, min, max)
103
+ return clamp(stepValue(newValue, step), min, max)
104
+ } else {
105
+ newValue = valueAsNumber + x
106
+ return stepValue(newValue, step)
107
+ }
108
+ },
109
+ [max, min, step, valueAsNumber],
110
+ )
111
+
112
+ const handleKeyDown = useCallback(
113
+ (event: React.KeyboardEvent<HTMLDivElement>) => {
114
+ if (!keyboard || !onChange || readonly) return
115
+ const key = event.key
116
+ if (!['ArrowUp', 'ArrowDown'].includes(key)) return
117
+ event.preventDefault()
118
+ const x = key == 'ArrowUp' ? keyboard[1] : -keyboard[1]
119
+ const parsed = parseValue(String(updateValueByEvent(keyboard[0], x)))
120
+ console.log('key control')
121
+ onChange?.(parsed.rawValue, parsed.formatValue)
122
+ },
123
+ [keyboard, readonly, onChange, updateValueByEvent],
124
+ )
125
+
126
+ const wheelRefCallback = useRefCallbackEvent(
127
+ 'wheel',
128
+ (event) => {
129
+ if (!wheel || readonly) return
130
+ event.preventDefault()
131
+ if (!onChange || event.deltaY == 0) return
132
+ const x = Math.sign(event.deltaY) * -wheel[1]
133
+ const parsed = parseValue(String(updateValueByEvent(wheel[0], x)))
134
+ console.log('wheel control')
135
+ onChange?.(parsed.rawValue, parsed.formatValue)
136
+ },
137
+ { passive: false },
138
+ [wheel, readonly, onChange, updateValueByEvent],
139
+ )
140
+
141
+ useImperativeHandle(ref, () => {
142
+ return {
143
+ focus() {
144
+ elmRef.current?.focus()
145
+ },
146
+ blur() {
147
+ elmRef.current?.blur()
148
+ },
149
+ }
150
+ }, [])
151
+
152
+ return (
153
+ <input
154
+ ref={(input) => {
155
+ elmRef.current = input
156
+ wheelRefCallback(input)
157
+ }}
158
+ className={clsx('tremolo-number-input', className)}
159
+ value={value}
160
+ min={min}
161
+ max={max}
162
+ step={step}
163
+ type="text"
164
+ aria-disabled={disabled}
165
+ aria-readonly={readonly}
166
+ tabIndex={-1}
167
+ data-error={error}
168
+ onChange={(event) => {
169
+ if (readonly) return
170
+ const v = event.currentTarget.value
171
+ const cursorPos = event.target.selectionStart
172
+ change(v)
173
+ const valueAsNumber = parseValue(v, units, digit).rawValue
174
+ onChange?.(valueAsNumber, v)
175
+ if (cursorPos) {
176
+ event.target.selectionStart = cursorPos
177
+ event.target.selectionEnd = cursorPos
178
+ }
179
+ }}
180
+ onFocus={(event) => {
181
+ setEditing(true)
182
+ const v = event.currentTarget.value
183
+ const parsed = parseValue(v, units, digit)
184
+ if (selectWithFocus == 'all') {
185
+ event.currentTarget.setSelectionRange(0, v.length)
186
+ } else if (selectWithFocus == 'number') {
187
+ event.currentTarget.setSelectionRange(
188
+ 0,
189
+ parsed.formatValue.length - parsed.unit.length,
190
+ )
191
+ }
192
+ onFocus?.(parsed.rawValue, parsed.formatValue, event)
193
+ }}
194
+ onBlur={(event) => {
195
+ setEditing(false)
196
+ // update value
197
+ let v = parseValue(event.currentTarget.value, units, digit).rawValue
198
+ if (clampValueOnBlur) {
199
+ v = safeClamp(v, min, max)
200
+ }
201
+ const parsed = parseValue(String(v), units, digit)
202
+ change(parsed.formatValue)
203
+ if (clampValueOnBlur) {
204
+ onChange?.(parsed.rawValue, parsed.formatValue)
205
+ }
206
+ onBlur?.(parsed.rawValue, parsed.formatValue, event)
207
+ }}
208
+ onKeyDown={(event) => {
209
+ if (blurOnEnter && event.key == 'Enter') {
210
+ event.currentTarget.blur()
211
+ }
212
+ handleKeyDown(event)
213
+ onKeyDown?.(event)
214
+ }}
215
+ {...props}
216
+ />
217
+ )
218
+ },
219
+ )
@@ -1,12 +1,14 @@
1
1
  import clsx from 'clsx'
2
2
  import { ComponentPropsWithoutRef, ReactNode } from 'react'
3
3
 
4
+ /** @category NumberInput */
4
5
  export interface StepperProps {
5
6
  /** Display only when hovering. */
6
7
  dynamic?: boolean
7
8
  children?: ReactNode
8
9
  }
9
10
 
11
+ /** @category NumberInput */
10
12
  export function Stepper({
11
13
  dynamic = true,
12
14
  children,
@@ -7,12 +7,14 @@ import { parseValue, Units } from '@tremolo-ui/functions/NumberInput'
7
7
  type State = {
8
8
  value: string
9
9
  valueAsNumber: number
10
+ step: number
11
+
10
12
  min?: number
11
13
  max?: number
12
- step?: number
13
- keepWithinRange?: boolean
14
14
  units?: string | Units
15
15
  digit?: number
16
+ readonly?: boolean
17
+ keepWithinRange?: boolean
16
18
  onChange?: (value: number, text: string) => void
17
19
  }
18
20
 
@@ -41,6 +43,7 @@ const createNumberInputStore = (initProps?: ProviderProps) => {
41
43
  min: 0,
42
44
  max: 0,
43
45
  step: 1,
46
+ readonly: false,
44
47
  keepWithinRange: true,
45
48
  onChange: (_v: number, _t: string) => {},
46
49
  }
@@ -62,9 +65,13 @@ const createNumberInputStore = (initProps?: ProviderProps) => {
62
65
  },
63
66
  increment: () =>
64
67
  set((state) => {
65
- let next =
66
- parseValue(state.value, state.units, state.digit).rawValue +
67
- (state.step ?? 1)
68
+ if (state.readonly) return {}
69
+ const current = parseValue(
70
+ state.value,
71
+ state.units,
72
+ state.digit,
73
+ ).rawValue
74
+ let next = current + (state.step ?? 1)
68
75
  if (state.keepWithinRange) {
69
76
  next = safeClamp(next, state.min, state.max)
70
77
  }
@@ -77,9 +84,13 @@ const createNumberInputStore = (initProps?: ProviderProps) => {
77
84
  }),
78
85
  decrement: () =>
79
86
  set((state) => {
80
- let next =
81
- parseValue(state.value, state.units, state.digit).rawValue -
82
- (state.step ?? 1)
87
+ if (state.readonly) return {}
88
+ const current = parseValue(
89
+ state.value,
90
+ state.units,
91
+ state.digit,
92
+ ).rawValue
93
+ let next = current - (state.step ?? 1)
83
94
  if (state.keepWithinRange) {
84
95
  next = safeClamp(next, state.min, state.max)
85
96
  }
@@ -92,6 +103,7 @@ const createNumberInputStore = (initProps?: ProviderProps) => {
92
103
  }),
93
104
  change: (value) =>
94
105
  set((state) => {
106
+ if (state.readonly) return {}
95
107
  const v = value ?? ''
96
108
  return {
97
109
  value: v,
@@ -1,40 +1,78 @@
1
1
  .tremolo-number-input-wrapper {
2
- --tremolo-number-input-border-radius: 4px;
3
- --tremolo-number-input-stepper-width: 20px;
2
+ --border-radius: 4px;
3
+ --stepper-width: 20px;
4
+ --active-color: var(--tremolo-theme-color);
4
5
 
5
6
  display: inline-flex;
6
7
  flex-direction: row;
7
8
  position: relative;
8
-
9
- border-style: solid;
10
- border-width: 1px;
11
- border-color: #bbb;
12
- border-radius: var(--tremolo-number-input-border-radius);
13
-
14
9
  width: 140px;
15
10
  height: min-content;
16
-
17
- &:hover {
18
- border-color: var(--tremolo-theme-color);
19
- }
11
+ border-style: solid;
12
+ border-color: #c1c1c1;
13
+ border-width: 0px;
14
+ outline: none;
15
+ transition: all 0.1s;
20
16
 
21
17
  &:not(:focus-within):has(> .tremolo-number-input[data-error='true']) {
22
18
  border-color: #f34343;
23
19
  }
24
20
 
25
- &:focus-within {
26
- border-color: var(--tremolo-theme-color);
27
- box-shadow: 0px 0px 0px 2px rgba(var(--tremolo-theme-color-rgb), 0.1);
21
+ &[data-variant='outline'] {
22
+ border-width: 1px;
23
+ border-radius: var(--border-radius);
24
+
25
+ &:hover {
26
+ border-color: #909090;
27
+ }
28
+
29
+ &:focus-within {
30
+ border-color: var(--active-color);
31
+ box-shadow: 0px 0px 0px 2px
32
+ color-mix(in srgb, var(--active-color) 10%, transparent);
33
+ }
34
+ }
35
+
36
+ &[data-variant='filled'] {
37
+ border-width: 1px;
38
+ border-radius: var(--border-radius);
39
+ border-color: transparent;
40
+ background-color: #edf2f7;
41
+
42
+ &:hover {
43
+ background-color: #e4e9ee;
44
+ }
45
+
46
+ &:focus-within {
47
+ background-color: inherit;
48
+ border-color: var(--active-color);
49
+ box-shadow: 0px 0px 0px 2px
50
+ color-mix(in srgb, var(--active-color) 10%, transparent);
51
+ }
52
+ }
53
+
54
+ &[data-variant='flushed'] {
55
+ border-bottom-width: 1px;
56
+
57
+ &:hover {
58
+ border-color: #909090;
59
+ }
60
+
61
+ &:focus-within {
62
+ border-color: var(--active-color);
63
+ box-shadow: 0px 2px 0px 0px
64
+ color-mix(in srgb, var(--active-color) 10%, transparent);
65
+ }
28
66
  }
29
67
 
30
68
  &[data-stepper='false'] {
31
- --tremolo-number-input-stepper-width: 0px;
69
+ --stepper-width: 0px;
32
70
  }
33
71
  }
34
72
 
35
73
  .tremolo-number-input {
36
74
  display: block;
37
- width: calc(100% - 20px - var(--tremolo-number-input-stepper-width));
75
+ width: calc(100% - 20px - var(--stepper-width));
38
76
  background-color: inherit;
39
77
  font: inherit;
40
78
  padding: 6px 10px;
@@ -42,7 +80,11 @@
42
80
  margin: 0;
43
81
  border: none;
44
82
  outline: none;
45
- appearance: textfield;
83
+ appearance: none;
84
+
85
+ &[aria-readonly='true'] {
86
+ cursor: not-allowed;
87
+ }
46
88
  }
47
89
 
48
90
  .tremolo-number-input-stepper {
@@ -52,7 +94,7 @@
52
94
  position: absolute;
53
95
  top: 0;
54
96
  right: 0;
55
- width: var(--tremolo-number-input-stepper-width);
97
+ width: var(--stepper-width);
56
98
  transition: all 0.1s linear;
57
99
 
58
100
  &[data-dynamic='true'] {
@@ -61,7 +103,11 @@
61
103
  }
62
104
  }
63
105
 
64
- .tremolo-number-input-wrapper:hover .tremolo-number-input-stepper {
106
+ :is(
107
+ .tremolo-number-input-wrapper:hover,
108
+ .tremolo-number-input-wrapper:focus-within
109
+ )
110
+ .tremolo-number-input-stepper {
65
111
  opacity: 1;
66
112
  transform: translateX(0);
67
113
  }
@@ -78,7 +124,7 @@
78
124
  max-height: 50%;
79
125
  user-select: none;
80
126
  cursor: pointer;
81
- border-top-right-radius: var(--tremolo-number-input-border-radius);
127
+ border-top-right-radius: var(--border-radius);
82
128
 
83
129
  &[aria-disabled='false']:active {
84
130
  background-color: #3443560e;
@@ -87,6 +133,10 @@
87
133
  &[aria-disabled='true'] {
88
134
  cursor: not-allowed;
89
135
  }
136
+
137
+ &[aria-readonly='true'] {
138
+ cursor: not-allowed;
139
+ }
90
140
  }
91
141
 
92
142
  .tremolo-number-input-decrement-stepper {
@@ -102,7 +152,7 @@
102
152
  max-height: 50%;
103
153
  user-select: none;
104
154
  cursor: pointer;
105
- border-bottom-right-radius: var(--tremolo-number-input-border-radius);
155
+ border-bottom-right-radius: var(--border-radius);
106
156
 
107
157
  &[aria-disabled='false']:active {
108
158
  background-color: #3443560e;
@@ -111,4 +161,8 @@
111
161
  &[aria-disabled='true'] {
112
162
  cursor: not-allowed;
113
163
  }
164
+
165
+ &[aria-readonly='true'] {
166
+ cursor: not-allowed;
167
+ }
114
168
  }