touchbar-electron-renderer
v0.3.4
Published
A React renderer for building declarative touchbar interfaces for Electron in Mac OSX.
Downloads
21
Maintainers
Readme
touchbar-electron-renderer
A React renderer for building declarative touchbar interfaces for Electron in Mac OSX.
This library is in alpha state, use at your own risk
Getting started
First install dependency
npm i touchbar-electron-renderer --save
Create a simple touchbar interface.
import { app, BrowserWindow, TouchBar as NativeTouchBar } from 'electron';
import React, { Component, Fragment } from 'react';
import { ReactTouchBar, TouchBar } from 'touchbar-electron-renderer';
const getRandomValue = () => {
const values = ['🍒', '💎', '7️⃣', '🍊', '🔔', '⭐', '🍇', '🍀']
return values[Math.floor(Math.random() * values.length)]
}
class App extends Component {
constructor(props) {
super(props);
this.state = {
reel1: null,
reel2: null,
reel3: null,
result: null,
resultColor: null,
}
this.doSpin = this.doSpin.bind(this);
}
updateReels() {
this.setState({
reel1: getRandomValue(),
reel2: getRandomValue(),
reel3: getRandomValue(),
});
}
finishSpin() {
const { reel1, reel2, reel3 } = this.state;
const uniqueValues = new Set([reel1, reel2, reel3]).size;
if (uniqueValues === 1) {
// All 3 values are the same
this.setState({
result: '💰 Jackpot!',
resultColor: '#FDFF00',
});
} else if (uniqueValues === 2) {
// 2 values are the same
this.setState({
result: '😍 Winner!',
resultColor: '#FDFF00',
});
} else {
// No values are the same
this.setState({
result: '🙁 Spin Again',
resultColor: null,
});
}
this.spinning = false;
}
doSpin() {
if (this.spinning) {
return;
}
this.spinning = true;
this.setState({
result: null,
});
let timeout = 10
const spinLength = 4 * 1000 // 4 seconds
const startTime = Date.now();
const spinReels = () => {
this.updateReels()
if ((Date.now() - startTime) >= spinLength) {
this.finishSpin();
} else {
// Slow down a bit on each spin
timeout *= 1.1
setTimeout(spinReels, timeout)
}
}
spinReels()
}
render() {
const { reel1, reel2, reel3, result, resultColor } = this.state;
return (
<Fragment>
<button backgroundColor="#7851A9" onClick={this.doSpin}>
🎰 Spin
</button>
<spacer large />
<label>{reel1}</label>
<spacer small />
<label>{reel2}</label>
<spacer small />
<label>{reel3}</label>
<spacer large />
<label color={resultColor}>{result}</label>
</Fragment>
);
}
}
function render() {
ReactTouchBar.render(<App />, new TouchBar(window, NativeTouchBar));
}
let window;
app.once('ready', () => {
window = new BrowserWindow({
frame: false,
titleBarStyle: 'hiddenInset',
width: 200,
height: 200,
backgroundColor: '#000'
});
window.loadURL('about:blank');
render();
})
API
For further reference about TouchBar
classes, check the official documentation.
TouchBar
Create TouchBar layouts for native macOS applications
Only the root element should be a TouchBar
. The children of TouchBar should be contained in a
Fragment
or <>
element.
Constructor arguments
- window: The electron window.
Example
const App = () => (
<>
<label>Hello world</label>
<label>This is a touchbar</label>
</>
)
ReactTouchBar.render(<App />, new TouchBar(window));
TouchBarButton, <button />
Create a button in the touch bar for native macOS applications
<button onClick={someCallback} icon={someIcon}>This is a button</button>
Props
- children: String,
<button />
only accepts text as children. It'll be mapped tolabel
. - onClick: Function, It'll be mapped to
click
in the native element. - icon: NativeImage, Button's Icon.
- iconPosition: String, Can be
left
,right
oroverlay
. - backgroundColor: String, background color.
Note: Use only Hex colors.
For more information go here.
TouchBarColorPicker, <color-picker />
Create a color picker in the touch bar for native macOS applications
<color-picker onChange={chooseColor} selected="#f2a4af">
<color>#f2a4af</color>
<color>#d9b1b1</color>
<color>#bb95a4</color>
<color>#b3ad99</color>
<color>#a3b9b7</color>
<color>#b1b1b0</color>
</color-picker>
Props
- selected: String, selected color.
- children: Only
<color />
are valid children of<color-picker
. - onChange: Function, Called when user chooses color.
- color: String, The chosen color.
<color />
Only valid as children of <color-picker />
<color>#b1b1b0</color>
Props
- children: String, Hex color.
For more information go here.
TouchBarGroup, <group />
Create a group in the touch bar for native macOS applications
<group>
<label>Foo bar</label>
<button>Hello World</button>
</group>
Props
- children: TouchBar elements.
For more information go here.
TouchBarLabel, <label />
Create a label in the touch bar for native macOS applications
<label color="#f2a4af">Hello world</label>
Props
- children: String,
<label />
only accepts text as children. It'll be mapped tolabel
. - color: String, Hex color for text. It'll be mapped to
textColor
.
For more information go here.
TouchBarPopover, <popover />
Create a popover in the touch bar for native macOS applications
<popover label="😀">
<button>A button in a popover</button>
<label>You can use any valid TouchBar element here.</label>
</popover>
Props
- label: String, Popover button text.
- icon: NativeImage, Popover's Icon.
- children: Touchbar elements.
- hideCloseButton: Boolean,
true
to hide the close button of the popover. Defaultfalse
. It'll be mapped & negated toshowCloseButton
. The reason for this is because is easier to read<popover hideCloseButton />
than<popover showCloseButton={false} />
.
For more information go here.
TouchBarScrubber, <scrubber />
Create a scrubber (a scrollable selector)
<scrubber onHighlight={someCallback}>
<scrub-item>😀</scrub-item>
<scrub-item>😁</scrub-item>
<scrub-item>😎</scrub-item>
</scrubber>
Props
- children: Only
<scrub-item />
elements are valid. - onSelect: Function, Called when the user taps an item that was not the last tapped item. It'll be mapped to
select
.- selectedIndex: Integer, The index of the item the user selected.
- onHighlight: Function, Called when the user taps any item. It'll be mapped to
highlight
.- highlightedIndex Integer, The index of the item the user touched.
- debounceTime: Integer, used to debounce
onSelect
andonHighlight
, default 250. - selectedStyle: String, Represents the style that selected items in the scrubber should have. Possible values:
background
, Maps to[NSScrubberSelectionStyle roundedBackgroundStyle]
.outline
, Maps to[NSScrubberSelectionStyle outlineOverlayStyle]
.null
, Actually null, not a string, removes all styles.
- overlayStyle: String, Represents the style that selected items in the scrubber should have. This style is overlayed on top of the scrubber item instead of being placed behind it. Possible values:
background
, Maps to[NSScrubberSelectionStyle roundedBackgroundStyle]
.outline
, Maps to[NSScrubberSelectionStyle outlineOverlayStyle]
.null
, Actually null, not a string, removes all styles.
- showArrowButtons: Boolean, represents whether to show the left / right selection arrows in this scrubber.
- mode: String, represents the mode of this scrubber. Possible values:
fixed
, Maps toNSScrubberModeFixed
.free
, Maps toNSScrubberModeFree
.
- continuous: Boolean, represents whether this scrubber is continuous or not.
<scrub-item />
Only valid as children of <scrubber />
<scrub-item icon={someIcon}>Some text</scrub-item>
Props
- children: String, only text is valid.
- icon: NativeImage.
For more information go here.
TouchBarSegmentedControl, <segmented-control />
Create a segmented control (a button group) where one button has a selected state
<segmented-control style="rounded" onChange={someCallback}>
<segment>Choose one button</segment>
<segment>Or another</segment>
<segment disabled>This segment is disabled</segment>
</segmented-control>
Props
- children: Only
<segment />
elements are valid. - segmentStyle: String, valid styles are:
automatic
- Default. The appearance of the segmented control is automatically determined based on the type of window in which the control is displayed and the position within the window.rounded
- The control is displayed using the rounded style.textured-rounded
- The control is displayed using the textured rounded style.round-rect
- The control is displayed using the round rect style.textured-square
- The control is displayed using the textured square style.capsule
- The control is displayed using the capsule style.small-square
- The control is displayed using the small square style.separated
- The segments in the control are displayed very close to each other but not touching.
- mode: String, Selection mode, valid modes are:
single
- Default. One item selected at a time, selecting one deselects the previously selected item.multiple
- Multiple items can be selected at a time.buttons
- Make the segments act as buttons, each segment can be pressed and released but never marked as active.
- selected: Integer, The index of the currently selected segment, will update automatically with user interaction. When the mode is multiple it will be the last selected item. It'll be mapped to
selectedIndex
. - onChange: Function, called when user chooses a segment.
- selectedIndex: Integer, The index of the segment the user selected.
- isSelected: Boolean, Whether as a result of user selection the segment is selected or not.
Only valid as children of <segmented-control />
.
<segment icon={someIcon} disabled>Hello world</segment>
Props
- children: String, only text is valid.
- icon: NativeImage.
- disabled: Boolean, if
true
then disable the segment. It'll be mapped and negated toenabled
.
For more information go here.
TouchBarSlider, <slider />
Create a slider in the touch bar for native macOS applications
<slider value={50} minValue={0} maxValue={100} onChange={someCallback}>Choose value</slider>
Props
- children: String, only text is valid, it'll be mapped to
label
. - value: Integer, selected value.
- minValue: Integer, Minimum value.
- maxValue: Integer, Maximum value.
- onChange: Function, called when the slider is changed. It'll be mapped to
change
.- newValue: Number, The value that the user selected on the Slider.
TouchBarSpacer, <spacer />
Create a spacer between two items in the touch bar for native macOS applications
<spacer large />
Props
- small: It'll be mapped to
size="small"
. - large: It'll be mapped to
size="large"
. - flexible: It'll be mapped to
size="flexible"
.
For more information go here.
Known issues
Scrubber updates
When using onHighlight
, it's called even when user is scrolling and didn't really chose a new element.
Hooks
For some reason, hooks
are not working properly. More investigation is needed.
Renderer
Lots of improvements are still needed. At this point, the code is more an ugly hack than a real solution.
Next steps
- [ ] Add tests.
- [ ] Write more complex examples.
- [ ] Fix bugs.
- [ ] Improve performance.
- [ ] Add support for esc key.